迭代地证明价值
好处:早期风险消减,更高的可预测性,涉众的信任
模式:使用一个迭代过程进行自适应的管理。首先解决主要技术,业务和风险。通过在每次迭代发布递增的用户价值获得反馈。
反模式:详细计划整个生命周期,用计划记录变数。详细计划是更好的计划。通过评审规格来评估状态。
这一原则下有若干隐含规则。首先,你想要交付增量价值来获得早期的和连续的反馈。这是通过把我们的项目划分为一组迭代过程实来现的。在每次迭代中,你完成一些需求,设计,实现,和对你的应用程序的测试,因此产生了一个距最终方案更进一步的发布。这使得你能够向终端用户和其它涉众演示应用程序,或让他们直接使用应用程序,使他们能够对你的工作做出快速的反馈。你进行的方向正确吗?涉众对你到目前为止的工作满意吗?你需要改变已经实现的特性吗?还有哪些特性需要被实现以增加业务价值?通过对这些问题做出令人满意的答复,你将会因发布实现涉众需要的系统在涉众中建立信任。同时你也不大会把工作做过头,加入对终端用户没有用处的功能3。
第二条规则是利用演示和反馈来调整你的计划。你需要做的不是依赖于评估规范,比如需求规范,设计模型,或者计划,你需要评估的是已经开发出来的代码的实际工作情况。这意味着你集中于测试结果并向不同涉众演示工作代码,使他们可以评估你的进展。这为你提供了一种良好理解,包括你在何处,在你的开发环境下团队可以以什么样的速度取得进展,以及为了成功完成项目你是否需要对过程进行校正。你使用这些信息来更新项目计划并为下一次迭代开发更详细的计划。
隐含的第三条规则是包含并管理变更。现在的应用程序太过复杂,以致你无法一次很好地排列需求,设计,实现,和测试。取而代之地是,最有效的应用程序开发方法包含了不可避免的变更。通过早期和连续的反馈,我们了解了如何改进应用程序,而迭代的方法为我们提供了逐渐实现这些变更的机会。所有这些变更需要通过合适的过程和工具来管理,这样我们就可以有效地管理变更而不影响我们的创造性。
这一原则隐含的第四条规则是在生命周期尽早发现关键风险4,如图1所示。你必须尽可能早地指出主要技术,业务和编程风险,而不是把风险的解决推迟到项目的最后。这是通过不断评估你面对的风险,并在下一次迭代中解决剩余风险中最重要的一个来实现的。在成功的项目中,早期的迭代包含涉众确定一个远景买进和高级需求,包括架构设计,实现,和用以减轻技术风险的测试。有一些信息需要被用来决定使用哪些可复用的主要资产或非销售(COTS)软件,保留这些信息也是很重要的。
图4:瀑布和迭代开发项目的风险消减一览图。迭代开发的一个主要目标是在早期消减风险。这是通过分析,排列优先级,和在每次迭代过程中解决最大风险来实现的。
一个典型的反模式(即,过去的导致项目失败的软件开发实践)是在整个生命周期开始前制定详细的计划,然后通过计划跟踪变化。另一个反模式是依赖于评审规格来在项目的前三分之二处评价项目状态,而不是评估测试结果和工作软件的演示情况。
提高抽象层次
好处:生产力,降低的复杂度
模式:复用已有资产,减少人类通过高级工具和语言产生的东西的数量,构建良好的弹性,质量,可理解性,和复杂度控制。
反模式:直接从模糊的高级需求发展出定制的代码构思。
在软件开发中我们面对的一个主要问题是复杂度。我们知道降低复杂度对生产力有很大影响。5在更高的抽象层次工作降低了复杂度并使交流变得容易。
一种有效降低复杂度的方法是复用已有资产,比如可复用的组件,继承系统,已有业务过程,模式,或者公开源码软件。两个关于复用的很好的例子在上一个十年对软件工业产生了巨大影响,它们是对中间件的复用,比如数据库,Web服务器和入口,以及后来的对公开源码软件的复用,它们提供了或大或小的可利用的组件。今后,Web服务可能会对复用产生主要影响,因为它们提供了在完全不同的平台上,以及客户和服务的提供者之间只有松散耦合的情况下复用主要的大块功能的简单方式,如图6所示。这意味着你可以更容易地采用不同的服务组合来实现业务需要。公开标准,比如RAS,UDDI,SOAP,WSDL,XML和UML,也方便了复用。
图5:通过面向服务的架构复用已有资产。 复用的问题之一是在开发时两个组件需要知道对方的存在。面向服务的架构通过提供所谓的“松散耦合”减轻了这个问题,在图中由黑色双箭头指示。某服务的客户可以动态地找到一个服务的提供者。因此你可以把已有的组件或继承系统包装起来,允许其它组件或应用程序通过一个基于标准的接口动态地访问它们的功能,并且这种访问是独立于平台和实现技术的。
另一种降低复杂度和改善交流的方法是利用高级工具,框架和语言。标准语言,比如统一建模语言(UML),和快速应用语言比如EGL6提供了表达高层构建,比如业务过程和服务组件,方便了其周围的高级构件的合作而同时隐藏了不必要的细节。设计和构建工具可以通过提供自动化设计,构建,和测试任务的向导来自动化从高级构件到工作代码的转移,而向导的自动化功能是通过产生代码和允许代码片段的使用,以及把集成和测试通过集成化开发,构建,和测试环境转变为无缝开发任务实现的。另一个例子是项目和证券管理工具,它们使你能够把多个项目的金融和其它方面作为一个实体来管理,而不是作为一组分离的实体来管理。
管理复杂度的第三种方法是集中于架构,无论你正试图定义一个业务还是开发一个系统或应用程序。在软件开发中,我们的目标是设计一个架构,实现它,并在项目的早期就进行测试。这意味着在项目的早期我们要定义高级构建模块和最重要的组件,它们的功能和接口。我们定义和实现系统机制,也就是对常见问题的现成解答,比如如何处理一致性和碎片收集。通过尽早正确建立架构,我们为系统定义了一个骨架,使得当我们向项目中加入更多的人,组件,功能和代码的时候管理复杂度比较容易。我们还认识到我们可以利用哪些可复用资产,以及系统的哪些方面需要定制。
这一原则的反模式是直接从模糊的高级需求发展出定制的代码构思。由于基本没有进行抽象,在代码级而不是一个更概念化的级别上进行了很多讨论,这就失去了很多复用等的机会。掌握的非形式化的需求和其它信息需要很多决定和规范来不断重新访问,而对架构的有限的强调造成了在项目后期的主要返工。