浅谈敏捷软件开发

首先,向想要了解和学习软件工程的同志们推荐一本好书:《敏捷软件开发:原则、模式与实践》,Robert C. Martin著,要看中文版的话就看邓辉译的那版。这本书怎么一个好,单看它获得2002年度技术图书类最高奖项——Jolt大奖,就可知它绝非一般的技术类图书。

以前参与过一个创业团队开发软件,当时我们的团队主要是由实习的研究生组成,我们都很有热情,想要从软件开发的过程和成果中获得成就感,因此乐此不疲,总盼着软件有上线的一天。可是越到后面,越感到怀疑、彷徨和疲惫,我们知道面向对象的设计原则、设计模式和重构等软件开发的相关观念,但更多时候我们将精力放在了如何架构项目、如何使用Jquery、ajax、css等来完成特定的功能和实现漂的动画效果等。通常,如果有人用js实现了某项会多处使用的功能,我们就会copy过来进行些微的改动来满足自己的需求。直到后来,这种泛滥的代码让我们觉得很不正常时,我们想到了抽象,但已为时太晚,我们专门选定了一个人来进行这项工作,但发现抽象的过程是缓慢的,艰难的,因为不单是此人还有我们这些代码的copy者都想着编写出新的代码而不想在已有的代码上滞留,这样一来,抽象的结果就很粗糙,甚至是不成功的。同样的心理,我们总想着把重构和测试留在最后面,可是越到后面,我们越怀疑重构和测试如何做起,等等,直到后来我们这批实习生被迫陆陆续续回到学校,都怀疑这个项目是否成功。

如今看到这本书之后,突然有了醍醐灌顶的感觉,真真有相见恨晚的感觉啊。

一 敏捷联盟宣言

2001年,敏捷联盟成立,并创建了一份价值观声明,即敏捷联盟宣言:

  • 个体交互       胜过    过程和工具
  • 可以工作的软件  胜过    面面俱到的文档
  • 客户合作       胜过    合同谈判
  • 响应变化     胜过    遵循计划

二 敏捷开发团队的特点

(1)我们最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意

已逐渐增加功能的方式经常性地交付系统和最终质量之间有非常强的相关性,交付的越频繁,最终产品的质量就越高。

(2)即使到了开发的后期,也欢迎改变需求。敏捷过程利用变化来为客户创造竞争优势。

(3)经常性地交付可以工作的软件,交付的间隔可以从几周到几个月,交付的时间间隔越短越好。

(4)在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。

(5)围绕被激励起来的个人来构建项目,给他们提供所需要的环境和支持,并且信任他们能够完成工作。

(6)在团队内部,最具有效果且富有效率的传递信息的方法就是面对面的交谈。

(7)工作的软件而非基础架构或代码是首要的进度度量标准。

(8)敏捷过程提倡可持续的开发速度,责任人、开发者和用户应该能够保持一个长期的、恒定的开发速度。

(9)不断地关注优秀的技能和好的设计会增强敏捷能力

团队应注重编写最高质量的代码,不能制造混乱然后告诉自己等有更多的时间再来清理它们,如果今天制造了混乱,就应该今天把混乱清理干净。

(10)简单

敏捷团队不会试图去构建那些华而不实的系统,他们不看重对于明天会出现的问题的预测,也不会在今天就对那些问题进行防卫。相反,他们在今天以最高质量完成最简单的工作。深信如果在明天发生了问题,也会很容易进行处理。

(11)最好的架构、需求和设计出自于自组织的团队

敏捷团队的成员共同来解决项目中所有方面的问题。每一个成员都具有项目中所有方面的参与权力。不存在单一的团队成员对系统架构、需求或者测试负责的情况。整个团队共同承担责任,每一个团队成员都能够影响它们。

(12)每隔一定时间,团队会在如何才能更有效地工作方面进行反省,然后相应地对自己的行为进行调整。

 三 极限编程概述

极限编程(eXtreme Programming,简称XP)是敏捷方法中最著名的一个,它由一系列互相依赖的实践组成,主要包含以下的实践内容:

(1)客户作为团队人员。客户,他们都是能够和团队一起工作的团队成员。

(2)用户素材

团队需要知道和项目需求相关的内容,但却无需知道的太多。XP中,我们和客户反复讨论,以获取对于需求细节的理解,但是不去捕获那些细节,我们更愿意客户在索引卡片上写下一些我们认可的词语,这些片言只语可以提醒我们记起这次交谈。用户素材(user stories)就是正在进行的关于需求谈话的助记符,它是一个计划工具。

(3)短交付周期

XP项目每两周交付一次可以工作的软件。每次迭代结束时,会给涉众演示迭代生成的系统,以得到他们的反馈。

(4)验收测试

验收测试使用能够让它们自动并且反复运行的某种脚本语言编写,这些测试共同来验证系统按照客户指定的行为运转。许多客户借助于QA来开发验收测试工具,并自己编写验收测试。

一旦通过一项验收测试,就将该测试加入到已经通过的验收测试集合中,并决不允许该测试再次失败。这个不断增长的验收测试集合每天会被多次运行,每当系统被创建时,都要运行这个验收测试集。如果一项验收测试失败了,那么系统创建就宣告失败。因而,一项需求一旦被实现,就再不会遭到破坏。

(5)结对编程

所有的产品代码都是由结对程序员使用同一台电脑共同完成的,结对成员中的一位控制键盘并输入代码,另一位观察输入的代码并寻找着代码中错误和可以改进的地方。两个人强烈地进行着交互,都全身心地投入到软件的编写中。

结对的关系每天至少需要改变一次,以便于每个程序员在一天中可以在两个不同的结对中工作。在每个迭代期间(2周),每个团队成员应该和所有其他的成员在一起工作过,并且应该参与了迭代中涉及的每项工作。这将极大地促进知识在团队中的传播。

(6)测试驱动的开发方法

首先编写一个单元测试,由于它要测试的功能还不存在,所以它会运行失败,然后编写代码使测试通过。测试用例和代码共同演化,测试用例循序渐进地对代码的编写进行指导。

如果结对的程序员对代码进行了小的更改,那么它们可以运行测试,以确保更改没有对程序造成任何的破坏,这会非常有利于重构。此外,为了编写能够通过测试的代码会激发成员解除各个模块之间的耦合,因而设计的耦合性也会较弱。

(7)集体所有权

结对编程中的每一对都具有拆出任何模块并对它进行改进的权力,没有程序员对任何一个特定的模块或技术单独负责。每个人都参与参与方面的工作,每个人都参与中间件方面的工作,每个人都参与数据库方面的工作,没有人比其他人在一个模块或技术上具有更多的权威。

(8)持续集成

 XP团队使用非阻塞的源代码控制工具。这意味着程序员可以在任何时候check out任何模块,而不管是否有其他人已经拆出这个模块。当程序员完成对模块的修改并把该模块拆入回去时,他必须把他所做的修改和在他前面拆入该模块的程序员所做的修改进行合并,为了避免合并的时间过长,团队的成员会非常频繁地拆入他们的模块。

(9)可持续的开发速度

软件项目不是全速的短,而是马拉松长跑。那些一越过起跑线就开始尽力狂奔的团队在远离终点前就会筋疲力尽。为了快速完成开发,团队必须要以一种可持续的速度前进,必须要有意识地保持稳定、适中的速度。

(10)开放的工作空间

团队在一个开放的房间中一起工作,房间里充满了交谈的嗡嗡声,结对编程的两人坐在互相能够听得到的距离内,每个人都可以得到另一人何时遇到了麻烦,每个人都了解对方的工作状态,程序员都处在适合于激烈第进行讨论的位置上。

(11)计划游戏

planning game的本质是划分业务人员和开发人员之间的职责。

(12)简单的设计

XP团队使设计尽可能地简单、具有表现力(expressive)。此外,他们仅仅关注于计划在本次迭代中要完成的用户素材,不会考虑那些未来的用户素材。在一次次的迭代中,他们不断变迁系统设计,使之对正在实现的用户素材而言始终保持在最优状态。

这意味着XP团队可能不会从基础结构开始,他们可能并不先去选择使用数据库或者中间件,只有当一个用户素材迫切需要基础结构时,他们才会引入该基础结构。

(13)重构(refactoring)

代码往往会腐化,随着我们添加一个又一个的特性,处理一个又一个的错误,代码的结构会逐渐退化。如果对此置之不理的话,这种退化最终会导致纠结不清,难于维护的混乱的代码。

XP团队通过经常性的代码重构来扭转这种退化,重构就是在不改变代码行为的前提下,对其进行一系列小的改造,旨在改进系统结构所有个改造都是微不足道的,几乎不值得去做,但是所有的改造叠加在一起,就形成了对系统设计和构造显著的改进。在每次细微改造之后,我们运行单元测试以确保改造没有造成任何破坏,然后再去做下一次改造,如此往复,周而复始,每次改造之后都要运行测试。

重构是持续进行的,而不是在项目结束时、发布版本时、迭代结束时、甚至每天快下班时才进行的。重构是我们每隔一个小时或半个小时就要去做的事情。通过重构,我们可以持续地保持尽可能干净、简单且具有表现力的代码。

(14)隐喻

隐喻(metaphore)是将所有系统联系在一起的全局视图,它是系统的未来景像,它使得所有单独模块的位置和外观都变得明显直观。如果模块的外观与整个系统的隐喻不符,就可知这个模块是错误的。

四 面向对象设计原则

面向对象设计有一些基本的原则,这些原则会有助于开发人员消除设计的中的拙劣症状。具体的见本分类中《面向对象设计基本原则》一节。下面列举主要的几个原则:

  • 单一职责原则
  • 开放——封闭原则
  • Liskov替换原则
  • 依赖倒置原则
  • 接口隔离原则

五 拙劣设计的症状

拙劣设计的症状也称设计中的臭味,是可以主观进行度量的,这些臭味常常是由于违反了上述原则中的一个或多个而导致的。当软件出现下面任何一种气味时,就表明软件正在腐化:

  • 僵化性(Rigidity):很难对系统进行改进,因为每个改动都会迫使许多对系统其他部分的其他改动。
  • 脆弱性(Fragility):进行一个改动时,程序的许多地方就可能会出现问题。常常是,出现新问题的地方与改动的地方并没有概念上的关联,要修正这些问题又会引出更多的问题,从而使开发团队就像一只不停追逐自己尾巴的狗一样忙的团团转。
  • 牢固性(Immobility):设计中包含了对其他系统有用的部分,但是要把这些部分从系统中分离出来所需要的努力和风险是巨大的。
  • 粘滞性(Viscosity):改动常常难以保持项目中的软件设计,应创建易于保持设计的系统和项目环境。
  • 不必要的复杂性(Needless Complexity):设计包含不具有任何好处的基础结构。
  • 不必要的重复(Needless Repetition):设计中包含有重复的结构,而该重复的结构本可以使用单一的抽象进行统一。
  • 晦涩性(Opacity):很难阅读、理解,没有很好地表现出意图。

六 结语

通常,敏捷开发人员会按照下面的方法来开发软件:

(1)遵循敏捷实践去发现问题;

(2)应用设计原则去诊断问题;

(3)应用适当的设计模式去解决问题。

敏捷设计是一个过程,不是一个事件,它是一个持续的应用原则、模式及实践来改进软件的结构和可读性的过程,它致力于保持系统设计在任何时间都尽可能的简单、干净以及富有表现力。敏捷设计中所应用的一些原则和模式不是事先设计好的,而是在一次次的迭代中进行被应用以使代码以及代码所表达的设计保持干净。 

原文地址:https://www.cnblogs.com/sophia-yun/p/3180578.html