﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-玄铁剑-文章分类-engineer</title><link>http://www.cnitblog.com/MartinYao/category/5589.html</link><description>成功的途径：抄，创造，研究，发明...</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 12:56:40 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 12:56:40 GMT</pubDate><ttl>60</ttl><item><title>系統架構考慮的因素</title><link>http://www.cnitblog.com/MartinYao/articles/28613.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Sun, 17 Jun 2007 05:01:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/28613.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/28613.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/28613.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/28613.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/28613.html</trackback:ping><description><![CDATA[<p>本文从程序的运行时结构和源代码的组织结构两个方面探讨了系统构架设计应考虑的各种因素，列举了系统构架设计文档应考虑的一些问题。约公元前25年，古罗马建筑师维特鲁威说：&#8220;理想的建筑师应该既是文学家又是数字家，他还应通晓历史，热衷于哲学研究，精通音乐，懂得医药知识，具有法学造诣，深谙天文学及天文计算。&#8221;（好难哪，软件构架设计师的要求呢？大家好好想想吧。）</p>
<p>关键字：系统构架、设计、考虑、因素<br>　<br>本文目录<br>　　一、与构架有关的几个基本概念；<br>　　二、构架设计应考虑的因素概揽；<br>　　三、程序的运行时结构方面的考虑；<br>　　四、源代码的组织结构方面的考虑；<br>　　五、写系统构架设计文档应考虑的问题<br>　　六、结语 </p>
<p>一、与构架有关的几个基本概念：</p>
<p>　　1、模块（module）：一组完成指定功能的语句，包括：输入、输出、逻辑处理功能、内部信息、运行环境（与功能对应但不是一对一关系）。</p>
<p>　　2、组件（component）：系统中相当重要的、几乎是独立的可替换部分，它在明确定义的构架环境中实现确切的功能。</p>
<p>　　3、模式（pattern）：指经过验证，至少适用于一种实用环境（更多时候是好几种环境）的解决方案模板（用于结构和行为。在 UML 中：模式由参数化的协作来表示，但 UML 不直接对模式的其他方面（如使用结果列表、使用示例等，它们可由文本来表示）进行建模。存在各种范围和抽象程度的模式，例如，构架模式、分析模式、设计模式和代码模式或实施模式。模式将可以帮助我们抓住重点。构架也是存在模式的。比如，对于系统结构设计，我们使用层模式；对于分布式系统，我们使用代理模式（通过使用代理来替代实际的对象，使程序能够控制对该对象的访问）；对于交互系统，我们使用MVC（M模型(对象)／V视图(输出管理)／C控制器(输入处理)）模式。模式是针对特定问题的解，因此，我们也可以针对需求的特点采用相应的模式来设计构架。</p>
<p>　　4、构架模式（architectural pattern）：表示软件系统的基本结构组织方案。它提供了一组预定义的子系统、指定它们的职责，并且包括用于组织其间关系的规则和指导。</p>
<p>　　5、层（layer）：对模型中同一抽象层次上的包进行分组的一种特定方式。通过分层，从逻辑上将子系统划分成许多集合，而层间关系的形成要遵循一定的规则。通过分层，可以限制子系统间的依赖关系，使系统以更松散的方式耦合，从而更易于维护。（层是对构架的横向划分，分区是对构架的纵向划分）。</p>
<p>　　6、系统分层的几种常用方法：<br>　　1） 常用三层服务：用户层、业务逻辑层、数据层；<br>　　2） 多层结构的技术组成模型：表现层、中间层、数据层；<br>　　3） 网络系统常用三层结构：核心层、汇聚层和接入层；<br>　　4） RUP典型分层方法：应用层、专业业务层、中间件层、系统软件层；<br>　　5） 基于Java的B/S模式系统结构：浏览器端、服务器端、请求接收层、请求处理层；<br>　　6） 某六层结构：功能层（用户界面）、模块层、组装层（软件总线）、服务层（数据处理）、数据层、核心层；</p>
<p>　　7、构架（Architecture，愿意为建筑学设计和建筑物建造的艺术与科学）: 在RUP中的定义：软件系统的构架（在某一给定点）是指系统重要构件的组织或结构，这些重要构件通过接口与不断减小的构件与接口所组成的构件进行交互；《软件构架实践》中的定义：某个软件或者计算系统的软件构架即组成该系统的一个或者多个结构，他们组成软件的各个部分，形成这些组件的外部可见属性及相互间的联系；IEEE 1471-2000中的定义：the fundamental organization of a system emboided in its components,their relationships to each other,and to the enviroment and the principles guiding its design and evolution，构架是系统在其所处环境中的最高层次的概念。软件系统的构架是通过接口交互的重要构件（在特定时间点）的组织或结构，这些构件又由一些更小的构件和接口组成。（&#8220;构架&#8221;可以作为名词，也可作为动词，作为动词的&#8220;构架&#8221;相当于&#8220;构架设计&#8221;）</p>
<p>　　8、构架的描述方式：&#8220;4＋1&#8221;视图（用例视图、设计视图、实现视图、过程视图、配置视图）是一个被广为使用的构架描述的模型；RUP过程的构架描述模板在&#8220;4＋1&#8221;视图的基础上增加了可选的数据视图（从永久性数据存储方面来对系统进行说明）；HP公司的软件描述模板也是基于&#8220;4＋1&#8221;视图。</p>
<p>　　9、结构：软件构架是多种结构的体现，结构是系统构架从不同角度观察所产生的视图。就像建筑物的结构会随着观察动机和出发点的不同而有多种含义一样，软件构架也表现为多种结构。常见的软件结构有：模块结构、逻辑或概念结构、进程或协调结构、物理结构、使用结构、调用结构、数据流、控制流、类结构等等。 </p>
<p>二、构架设计应考虑的因素概揽：</p>
<p>　　模块构架设计可以从程序的运行时结构和源代码的组织结构方面考虑。</p>
<p>　　1、程序的运行时结构方面的考虑：<br>　　1） 需求的符合性：正确性、完整性；功能性需求、非功能性需求；<br>　　2） 总体性能（内存管理、数据库组织和内容、非数据库信息、任务并行性、网络多人操作、关键算法、与网络、硬件和其他系统接口对性能的影响）；<br>　　3） 运行可管理性：便于控制系统运行、监视系统状态、错误处理；模块间通信的简单性；与可维护性不同；<br>　　4） 与其他系统接口兼容性；<br>　　5） 与网络、硬件接口兼容性及性能；<br>　　6） 系统安全性；<br>　　7） 系统可靠性；<br>　　8） 业务流程的可调整性；<br>　　9） 业务信息的可调整性<br>　　10） 使用方便性<br>　　11） 构架样式的一致性<br>　　注：运行时负载均衡可以从系统性能、系统可靠性方面考虑。</p>
<p>　　2、源代码的组织结构方面的考虑：<br>　　1） 开发可管理性：便于人员分工（模块独立性、开发工作的负载均衡、进度安排优化、预防人员流动对开发的影响）、利于配置管理、大小的合理性与适度复杂性；<br>　　2） 可维护性：与运行可管理性不同；<br>　　3） 可扩充性：系统方案的升级、扩容、扩充性能；<br>　　4） 可移植性：不同客户端、应用服务器、数据库管理系统；<br>　　5） 需求的符合性（源代码的组织结构方面的考虑）。 </p>
<p>三、程序的运行时结构方面的考虑：</p>
<p>　　1、 需求的符合性：正确性、完整性；功能性需求、非功能性需求软件项目最主要的目标是满足客户需求。在进行构架设计的时候，大家考虑更多的是使用哪个运行平台、编成语言、开发环境、数据库管理系统等问题，对于和客户需求相关的问题考虑不足、不够系统。如果无论怎么好的构架都无法满足客户明确的某个功能性需求或非功能性需求，就应该与客户协调在项目范围和需求规格说明书中删除这一需求。否则，架构设计应以满足客户所有明确需求为最基本目标，尽量满足其隐含的需求。（客户的非功能性需求可能包括接口、系统安全性、可靠性、移植性、扩展性等等，在其他小节中细述）<br>　　一般来说，功能需求决定业务构架、非功能需求决定技术构架，变化案例决定构架的范围。需求方面的知识告诉我们，功能需求定义了软件能够做些什么。我们需要根据业务上的需求来设计业务构架，以使得未来的软件能够满足客户的需要。非功能需求定义了一些性能、效率上的一些约束、规则。而我们的技术构架要能够满足这些约束和规则。变化案例是对未来可能发生的变化的一个估计，结合功能需求和非功能需求，我们就可以确定一个需求的范围，进而确定一个构架的范围。（此段From林星）<br>　　这里讲一个前几年因客户某些需求错误造成构架设计问题而引起系统性能和可靠性问题的小小的例子：此系统的需求本身是比较简单的，就是将某城市的某业务的全部历史档案卡片扫描存储起来，以便可以按照姓名进行查询。需求阶段客户说卡片大约有20万张，需求调研者出于对客户的信任没有对数据的总量进行查证。由于是中小型数据量，并且今后数据不会增加，经过计算20万张卡片总体容量之后，决定使用一种可以单机使用也可以联网的中小型数据库管理系统。等到系统完成开始录入数据时，才发现数据至少有60万，这样使用那种中小型数据库管理系统不但会造成系统性能的问题，而且其可靠性是非常脆弱的，不得不对系统进行重新设计。从这个小小的教训可以看出，需求阶段不仅对客户的功能需求要调查清楚，对于一些隐含非功能需求的一些数据也应当调查清楚，并作为构架设计的依据。<br>　　对于功能需求的正确性，在构架设计文档中可能不好验证（需要人工、费力）。对于功能需求完整性，就应当使用需求功能与对应模块对照表来跟踪追溯。对于非功能需求正确性和完整性，可以使用需求非功能与对应设计策略对照表来跟踪追溯评估。<br>　　&#8220;软件设计工作只有基于用户需求，立足于可行的技术才有可能成功。&#8221;</p>
<p>　　2、 总体性能<br>　　性能其实也是客户需求的一部分，当然可能是明确的，也有很多是隐含的，这里把它单独列出来在说明一次。性能是设计方案的重要标准，性能应考虑的不是单台客户端的性能，而是应该考虑系统总的综合性能；<br>　　性能设计应从以下几个方面考虑：内存管理、数据库组织和内容、非数据库信息、任务并行性、网络多人操作、关键算法、与网络、硬件和其他系统接口对性能的影响；<br>　　几点提示：算法优化及负载均衡是性能优化的方向。经常要调用的模块要特别注意优化。占用内存较多的变量在不用时要及时清理掉。需要下载的网页主题文件过大时应当分解为若干部分，让用户先把主要部分显示出来。</p>
<p>　　3、 运行可管理性<br>　　系统的构架设计应当为了使系统可以预测系统故障，防患于未然。现在的系统正逐步向复杂化、大型化发展，单靠一个人或几个人来管理已显得力不从心，况且对于某些突发事件的响应，人的反应明显不够。因此通过合理的系统构架规划系统运行资源，便于控制系统运行、监视系统状态、进行有效的错误处理；为了实现上述目标，模块间通信应当尽可能简单，同时建立合理详尽的系统运行日志，系统通过自动审计运行日志，了解系统运行状态、进行有效的错误处理；（运行可管理性与可维护性不同）</p>
<p>　　4、 与其他系统接口兼容性（解释略）</p>
<p>　　5、 与网络、硬件接口兼容性及性能（解释略）</p>
<p>　　6、 系统安全性<br>　　随着计算机应用的不断深入和扩大，涉及的部门和信息也越来越多，其中有大量保密信息在网络上传输，所以对系统安全性的考虑已经成为系统设计的关键，需要从各个方面和角度加以考虑，来保证数据资料的绝对安全。</p>
<p>　　7、 系统可靠性<br>　　系统的可靠性是现代信息系统应具有的重要特征，由于人们日常的工作对系统依赖程度越来越多，因此系统的必须可靠。系统构架设计可考虑系统的冗余度，尽可能地避免单点故障。系统可靠性是系统在给定的时间间隔及给定的环境条件下，按设计要求，成功地运行程序的概率。成功地运行不仅要保证系统能正确地运行，满足功能需求，还要求当系统出现意外故障时能够尽快恢复正常运行，数据不受破坏。</p>
<p>　　8、 业务流程的可调整性<br>　　应当考虑客户业务流程可能出现的变化，所以在系统构架设计时要尽量排除业务流程的制约，即把流程中的各项业务结点工作作为独立的对象，设计成独立的模块或组件，充分考虑他们与其他各种业务对象模块或组件的接口，在流程之间通过业务对象模块的相互调用实现各种业务，这样，在业务流程发生有限的变化时（每个业务模块本身的业务逻辑没有变的情况下），就能够比较方便地修改系统程序模块或组件间的调用关系而实现新的需求。如果这种调用关系被设计成存储在配置库的数据字典里，则连程序代码都不用修改，只需修改数据字典里的模块或组件调用规则即可。</p>
<p>　　9、 业务信息的可调整性<br>　　应当考虑客户业务信息可能出现的变化，所以在系统构架设计时必须尽可能减少因为业务信息的调整对于代码模块的影响范围。</p>
<p>　　10、 使用方便性<br>　　使用方便性是不须提及的必然的需求，而使用方便性与系统构架是密切相关的。WinCE（1.0）的失败和后来改进版本的成功就说明了这个问题。WinCE（1.0）有太多层次的视窗和菜单，而用户则更喜欢简单的界面和快捷的操作。失败了应当及时纠正，但最好不要等到失败了再来纠正，这样会浪费巨大的财力物力，所以在系统构架阶段最好能将需要考虑的因素都考虑到。当然使用方便性必须与系统安全性协调平衡统一，使用方便性也必须与业务流程的可调整性和业务信息的可调整性协调平衡统一。&#8220;满足用户的需求，便于用户使用，同时又使得操作流程尽可能简单。这就是设计之本。&#8221;</p>
<p>　　11、构架样式的一致性<br>　　软件系统的构架样式有些类似于建筑样式（如中国式、哥特式、希腊复古式）。软件构架样式可分为数据流构架样式、调用返回构架样式、独立组件构架样式、以数据为中心的构架样式和虚拟机构架样式，每一种样式还可以分为若干子样式。构架样式的一致性并不是要求一个软件系统只能采用一种样式，就像建筑样式可以是中西结合的，软件系统也可以有异质构架样式（分为局部异质、层次异质、并行异质），即多种样式的综合，但这样的综合应该考虑其某些方面的一致性和协调性。每一种样式都有其使用的时机，应当根据系统最强调的质量属性来选择。 </p>
<p>四、源代码的组织结构方面的考虑：</p>
<p>　　1、 开发可管理性</p>
<p>　　便于人员分工（模块独立性、开发工作的负载均衡、进度安排优化、预防人员流动对开发的影响：一个好的构架同时应有助于减少项目组的压力和紧张，提高软件开发效率）、利于配置管理、大小的合理性、适度复杂性；</p>
<p>　　1）便于人员分工－模块独立性、层次性<br>　　模块独立性、层次性是为了保证项目开发成员工作之间的相对独立性，模块联结方式应该是纵向而不是横向, 模块之间应该是树状结构而不是网状结构或交叉结构，这样就可以把开发人员之间的通信、模块开发制约关系减到最少。同时模块独立性也比较利于配置管理工作的进行。现在有越来越多的的软件开发是在异地进行，一个开发组的成员可能在不同城市甚至在不同国家，因此便于异地开发的人员分工与配置管理的源代码组织结构是非常必要的。</p>
<p>　　2）便于人员分工－开发工作的负载均衡<br>　　不仅仅是开发出来的软件系统需要负载均衡，在开发过程中开发小组各成员之间工作任务的负载均衡也是非重要的。所谓工作任务的负载均衡就是通过合理的任务划分按照开发人员特点进行分配任务，尽量让项目组中的每个人每段时间都有用武之地。这就需要在构架设计时应当充分考虑项目组手头的人力资源，在实现客户需求的基础上实现开发工作的负载均衡，以提高整体开发效率。</p>
<p>　　3）便于人员分工－进度安排优化；<br>　　进度安排优化的前提是模块独立性并搞清楚模块开发的先后制约关系。利用工作分解结构对所有程序编码工作进行分解，得到每一项工作的输入、输出、所需资源、持续时间、前期应完成的工作、完成后可以进行的工作。然后预估各模块需要时间，分析各模块的并行与串行（顺序制约），绘制出网络图，找出影响整体进度的关键模块，算出关键路径，最后对网络图进行调整，以使进度安排最优化。<br>有个家喻户晓的智力题叫烤肉片策略：约翰逊家户外有一个可以同时烤两块肉片的烤肉架，烤每块肉片的每一面需要10分钟，现要烤三块肉片给饥肠辘辘急不可耐的一家三口。问题是怎样才能在最短的时间内烤完三片肉。一般的做法花20分钟先烤完前两片，再花20分钟烤完第三片。有一种更好的方法可以节省10分钟，大家想想。</p>
<p>　　4）便于人员分工－预防员工人员流动对开发的影响<br>　　人员流动在软件行业是司空见惯的事情，已经是一个常见的风险。作为对这一风险的有效的防范对策之一，可以在构架设计中考虑到并预防员工人员流动对开发的影响。主要的思路还是在模块的独立性上（追求高内聚低耦合），组件化是目前流行的趋势。</p>
<p>　　5）利于配置管理（独立性、层次性）<br>　　利于配置管理与利于人员分工有一定的联系。除了逻辑上的模块组件要利于人员分工外，物理上的源代码层次结构、目录结构、各模块所处源代码文件的部署也应当利于人员分工和配置管理。（尽管现在配置管理工具有较强大的功能，但一个清楚的源码分割和模块分割是非常有好处的）。</p>
<p>　　6）大小的合理性与适度复杂性<br>　　大小的合理性与适度复杂性可以使开发工作的负载均衡，便于进度的安排，也可以使系统在运行时减少不必要的内存资源浪费。对于代码的可阅读性和系统的可维护性也有一定的好处。另外，过大的模块常常是系统分解不充分，而过小的模块有可能降低模块的独立性，造成系统接口的复杂。</p>
<p>　　2、 可维护性<br>　　便于在系统出现故障时及时方便地找到产生故障的原因和源代码位置，并能方便地进行局部修改、切割；（可维护性与运行可管理性不同）</p>
<p>　　3、 可扩充性：系统方案的升级、扩容、扩充性能<br>　　系统在建成后会有一段很长的运行周期，在该周期内，应用在不断增加，应用的层次在不断升级，因此采用的构架设计等方案因充分考虑升级、扩容、扩充的可行性和便利</p>
<p>　　4、 可移植性<br>　　不同客户端、应用服务器、数据库管理系统：如果潜在的客户使用的客户端可能使用不同的操作系统或浏览器，其可移植性必须考虑客户端程序的可移植性，或尽量不使业务逻辑放在客户端；数据处理的业务逻辑放在数据库管理系统中会有较好的性能，但如果客户群中不能确定使用的是同一种数据库管理系统，则业务逻辑就不能数据库管理系统中；<br>　　达到可移植性一定要注重标准化和开放性：只有广泛采用遵循国际标准，开发出开放性强的产品，才可以保证各种类型的系统的充分互联，从而使产品更具有市场竞争力，也为未来的系统移植和升级扩展提供了基础。</p>
<p>　　5、 需求的符合性<br>　　从源代码的组织结构看需求的符合型主要考虑针对用户需求可能的变化的软件代码及构架的最小冗余（同时又要使得系统具有一定的可扩展性）。</p>
<p>五、写系统构架设计文档应考虑的问题</p>
<p>　　构架工作应该在需求开发完成约80％的时候开始进行，不必等到需求开发全部完成，需要项目经理以具体的判断来评估此时是否足以开始构建软件构架。<br>　　给出一致的轮廓：系统概述。一个系统构架需要现有概括的描述，开发人员才能从上千个细节甚至数十个模块或对象类中建立一致的轮廓。<br>　　构架的目标应该能够清楚说明系统概念，构架应尽可能简化，最好的构架文件应该简单、简短，清晰而不杂乱，解决方案自然。<br>　　构架应单先定义上层的主要子系统，应该描述各子系统的任务，并提供每个子系统中各模块或对象类的的初步列表。<br>　　构架应该描述不同子系统间相互通信的方式，而一个良好的构架应该将子系统间的通信关系降到最低。<br>　　成功构架的一个重要特色，在于标明最可能变更的领域，应当列出程序中最可能变更的部分，说明构架的其他部分如何应变。<br>　　复用分析、外购：缩短软件开发周期、降低成本的有效方案未必是自行开发软件，可以对现有软件进行复用或进行外购。应考虑其对构架的影响。<br>　　除了系统组织的问题，构架应重点考虑对于细节全面影响的设计决策，深入这些决策领域：外部软件接口（兼容性、通信方式、传递数据结构）、用户接口（用户接口和系统层次划分）、数据库组织和内容、非数据库信息、关键算法、内存管理（配置策略）、并行性、安全性、可移植性、网络多人操作、错误处理。<br>　　要保证需求的可追踪性，即保证每个需求功能都有相应模块去实现。<br>　　构架不能只依据静态的系统目标来设计，也应当考虑动态的开发过程，如人力资源的情况，进度要求的情况，开发环境的满足情况。构架必须支持阶段性规划，应该能够提供阶段性规划中如何开发与完成的方式。不应该依赖无法独立运行的子系统构架。将系统各部分的、依赖关系找出来，形成一套开发计划。 </p>
<p>六、结语</p>
<p>　　系统构架设计和千差万别的具体的开发平台密切相关，因此在此无法给出通用的解决方案，主要是为了说明哪些因素是需要考虑的。对于每个因素的设计策略和本文未提到的因素需要软件构架设计师在具体开发实践中灵活把握。不同因素之间有时是矛盾的，构架设计时需要根据具体情况进行平衡。 </p>
<p>参考文献<br>　 《软件构架实践》SEI软件工程译丛，林&#183;巴斯著<br>　 《微软项目：求生法则》Steve McConnell著，余孟学译<br>　 《实用软件工程》第二版，郑人杰、殷人昆、陶永雷等著<br>　 《软件工程：实践者的研究方法》（第5版）Roger S.Pressman著<br>　 《软件开发的科学与艺术》陈宏刚等著　　<br></p>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/28613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2007-06-17 13:01 <a href="http://www.cnitblog.com/MartinYao/articles/28613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>軟件工程</title><link>http://www.cnitblog.com/MartinYao/articles/28612.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Sun, 17 Jun 2007 05:00:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/28612.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/28612.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/28612.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/28612.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/28612.html</trackback:ping><description><![CDATA[<p>前言 </p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 无论什么过程都不能适用于任何项目，我们应该根据项目的特点去选择合适的过程。只有这样才能在过程一级保证项目的成功。 </p>
<p>地税部门对项目的组织采用rup及xp结合的方式，根据项目的特点来决定对rup及xp的侧重。但一个至高无上的目标是必须遵守的，就是以最快的速度向客户提交可执行的版本，而要做到这一点则必须坚持小步骤迭代及测试自动化。 </p>
<p>&nbsp; </p>
<p>过程分类<br>rup </p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 属于重量级的开发过程，强调分析设计及迭代开发。对于研发型项目，前期没有基础，在形成稳定的框架之前应该走一段分析设计的过程。形成稳定的开发框架之后，则应该转向敏捷过程。 </p>
<p>Xp </p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 属于轻量级开发过程，强调重构（编程中的设计）及测试自动化。对于有一定基础的项目应该是首选。 </p>
<p>&nbsp; </p>
<p>项目过程<br>约束 </p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每个开发人员必须将服务器上的weblogic拷贝至本地，对程序的修改基于vss在本地进行修改测试，数据库配置成开发专用数据库。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单元测试由开发人员自己负责，发布后的功能测试由测试组负责并将启用butterfly进行缺陷跟踪。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 发布专用数据库由ＤＢＡ单独负责。任何人不得更改。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开发过程中发现问题随时提出来，不要有事后诸葛亮得做法。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开发之前搞清楚需求，不要出现大的反工。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每天走之前简单描述自己的当前的工作成果，发送给开发负责人并抄送项目组所有成员，作为每天的工作周报。 </p>
<p>&nbsp; </p>
<p>工具<br>ant </p>
<p>vss </p>
<p>jdk </p>
<p>junit </p>
<p>checkStyle </p>
<p>数据库同步脚本 </p>
<p>rational rose </p>
<p>visio </p>
<p>butterfly </p>
<p>&nbsp; </p>
<p>核心思想 </p>
<p><br>&nbsp; 尽快提交版本 </p>
<p>&nbsp; 每日创建 </p>
<p>&nbsp; 持续集成 </p>
<p>&nbsp; 简单设计 </p>
<p>&nbsp; 自动化单元测试与重构 </p>
<p>&nbsp; 基于模型进行工作，自动化生成文档 </p>
<p>&nbsp; 自动化检查代码规范 </p>
<p>&nbsp; 自动化生成javadoc </p>
<p>&nbsp; 尽快提交版本<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 衡量进度最直接的方法是可运行的软件。所以开发过程一个终极目标是持续快速的提交版本。开发组以最快的速度提交版本，提供测试人员进行测试。经过项目组测试人员测试的版本，同样以最快的速度提交客户测试人员进行测试。为达到这个目标，必须建立相应的机制，达到版本的快速持续发布。通过测试得到反馈，而这些反馈能够驱动开发 </p>
<p>尽快提交版本包括： </p>
<p>&nbsp; 开发人员尽快的将代码提交到配置管理开发库中，最长不能超过一天 </p>
<p>&nbsp; 开发人员提交的代码必须是编译通过的 </p>
<p>&nbsp; 开发人员本地代码与配置开发库代码尽量保持一致 </p>
<p>&nbsp; 每日创建保证版本的快速全编译及部署，提供测试人员测试 </p>
<p>&nbsp; 每日创建<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开发组每天的工作成果，在每天发布的版本中充分体现。每天晚上进行全版本的编译发布，第二天测试人员进行测试，将结果反馈给开发组。每日创建的实现完全基于ant实现，通过定时任务每日进行。 </p>
<p>步骤： </p>
<p>&nbsp;&nbsp; 取得vss中最新源代码 </p>
<p>&nbsp;&nbsp; 取得vss中数据库操纵脚本并运行 </p>
<p>&nbsp;&nbsp; 生成ormap </p>
<p>&nbsp;&nbsp; 编译最新源代码 </p>
<p>&nbsp;&nbsp; 停服务器 </p>
<p>&nbsp;&nbsp; 完全删除老系统 </p>
<p>&nbsp;&nbsp; 部署新系统 </p>
<p>&nbsp;&nbsp; 启动服务器 </p>
<p>详细内容参见自动发布脚本 </p>
<p>&nbsp;&nbsp; 持续集成<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 具备了每日创建的机制后，每天开发组完成的新功能或修改的bug将在当天晚上集成发布到测试服务器上。这样，开发组可以得到测试结果的快速反馈，又促进了下一轮的迭代。 </p>
<p>&nbsp;&nbsp; 简单设计<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前整个系统已经具备稳定的开发框架，所以我们的业务实现可以设计拖后，开始进行简单设计，明确接口及xml格式，在编程中通过重构进行设计，时刻把握一点就是最快的发布版本。 </p>
<p>&nbsp;&nbsp; 自动化单元测试与重构<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为了达到最快速度的发布版本，我们可能会产生一个拙略的实现，这可以通过重构来在以后的版本中改进，当然，必须通过单元测试提供重构过程中的质量保证。 </p>
<p>&nbsp;&nbsp; 基于模型进行工作，自动化生成文档<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 维护模型比维护文档更轻松，在维护一致性方面也更有效。所以我们必须基于模型工作，而文档可以随时根据模板自动生成。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过rational rose建立一套分析设计模型，将rose与vss进行集成，整个项目组可以在整个模型上进行协作。通过定义rose模板实现文档的自动化。 </p>
<p>&nbsp;&nbsp; 自动化检查代码规范<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 代码规范的检查我们基于checkstyle进行，目前采用的检查模板是J2EE标准模板，我们可以开发自己的模板进行检查。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Checkstyle对程序命名规范，缩进规范等，通过与ant集成可以自动化，并生成结果报告。 </p>
<p>&nbsp;&nbsp; 自动化生成javadoc<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 系统的接口等文档通过javadoc生成，通过ant发布脚本在每天的版本发布中可以自动生成。为了达到我们要求的格式，可以自己定义xsl样式表。<br>对于框架稳定的软件，目前rup与xp相结合的软件开发过程，整个过程经历： </p>
<p>&nbsp;&nbsp; 发布计划、迭代计划及任务分配 </p>
<p>&nbsp;&nbsp; 用例（素材）分析 </p>
<p>&nbsp;&nbsp; 简单设计 </p>
<p>&nbsp;&nbsp; 测试驱动开发 </p>
<p>&nbsp;&nbsp; 重构与持续集成 </p>
<p>&nbsp;&nbsp; 版本迭代 </p>
<p>&nbsp;&nbsp; 配置、版本管理贯串整个过程 </p>
<p>角色包括： </p>
<p>需求分析人员：确认需求，理解需求，明示需求 </p>
<p>开发人员：设计、编码、单元测试 </p>
<p>测试人员：功能测试，一般与需求分析人员公用，客户人员进行验收测试更佳 </p>
<p>配置人员：开发环境的配置，包括配置管理、服务器配置等 </p>
<p>dba：数据库管理员 </p>
<p>发布计划、迭代计划及任务分配<br>发布计划：作为一次大的发布，一般给客户或测试人员一个完整的阶段性版本 </p>
<p>迭代计划：开发组内部迭代，可以每天多次，至少每天一次 </p>
<p>原则： </p>
<p>&nbsp; 任务细分：细化到每个功能模块的各个阶段，包括 </p>
<p>&nbsp; 需求人员分析 </p>
<p>&nbsp; 需求人员向开发人员讲解（内部评审） </p>
<p>&nbsp; 开发人员简单设计 </p>
<p>&nbsp; 开发人员多个版本迭代，尤其明确第一个提交测试的版本发布时间 </p>
<p>&nbsp; 责任到单个人：单人负责，杜绝多人负责同一项任务 </p>
<p>&nbsp; 明确第一个提交测试的迭代版本的时间点：明确第一个版本的发布时间至关重要，这也是测试驱动开发的起点 </p>
<p>&nbsp;&nbsp; 每个小版本迭代不超过一天，整个功能模块开发的迭代次数不超过一周 </p>
<p>&nbsp;&nbsp; 任务接受制：计划宣布，没有异议，视为接受任务，则严格按计划执行 </p>
<p>&nbsp;&nbsp; 计划中各任务的含义要当面说清楚，确保任务负责人明摆任务的具体含义 </p>
<p>用例（素材）分析<br>用例分析部分采用rational rose，整个小组在rose模型上协同工作，共同维护模型的一致性，通过建立&#8220;单元&#8221;以及rose与vss的集成保证模型完整性及一致性。实现对需求的统一管理。通过定义rose模板，实现文档的随时自动生成。 </p>
<p>需求人员组织内部评审时将分析的结果与开发人员进行交流，确保开发人员正确理解需求。需求人员完成的内容包括： </p>
<p>&nbsp; 业务逻辑分析 </p>
<p>&nbsp; 界面设计 </p>
<p>数据库表格初步设计<br>简单设计<br>目前开发框架基本稳定，具体业务的设计可以拖后，开发人员可以通过简单设计明确接口并快速进入版本迭代，在迭代过程中通过不断重构及持续集成来达到最佳设计。 </p>
<p>前置条件：开发人员正确理解需求分析的结果 </p>
<p>后置条件： </p>
<p>&nbsp; 明确包结构 </p>
<p>&nbsp; 明确类的职责 </p>
<p>&nbsp; 明确接口定义 </p>
<p>&nbsp; 明确参数的格式定义及其内在含义 </p>
<p>&nbsp; 内部评审通过 </p>
<p>测试驱动开发<br>测试的功效在测试之外，测试优先的原则，除了在实现前先写测试能够明确业务外，还可以促使开发人员在设计结构上进一步优化。每天运行的单元测试程序还能够尽早的发现程序中的错误，避免错误曝露延后带来的维护成本，也就在开发方法上保证了效率的提高。 </p>
<p>前置条件： </p>
<p>简单设计后，明确了接口定义及参数格式定义，对业务理解基本清楚 </p>
<p>后置条件： </p>
<p>&nbsp; 根据接口定义实现JUNIT测试代码，彻底明确业务 </p>
<p>&nbsp; 在没有具体实现的条件下，搭出业务实现框架，尽快发布版本 </p>
<p>&nbsp; 实现业务逻辑，频繁运行测试程序 </p>
<p>&nbsp; 进行多次版本迭代 </p>
<p>重构与持续集成<br>重构能够改善既有代码的设计，重构的过程是设计的过程，优化的过程。 </p>
<p>测试程序给重构提供了质量保证。 </p>
<p>重构结果通过持续集成体现在各版本中 </p>
<p>前置条件： </p>
<p>基本实现了业务框架，已经发布了第一个版本。也可以随时重构，但不能影响版本发布 </p>
<p>后置条件： </p>
<p>&nbsp; 优化了程序结构 </p>
<p>&nbsp; 优化代码质量 </p>
<p>&nbsp; 修改了bug </p>
<p>代码review的过程 </p>
<p>版本迭代<br>通过版本迭代快速准确的体现目前的项目进度。给管理人员明确的进度展示。参考进度如下： </p>
<p>&nbsp; </p>
<p>阶段 <br>&nbsp;衡量标准 <br>&nbsp;完成 </p>
<p>确认人 <br>&nbsp;周期 </p>
<p>估计值 <br>&nbsp;完成 </p>
<p>百分比 <br>&nbsp;<br>需求确认 <br>&nbsp;指根据需求文档与需求人员进行确认后，对以下内容深入理解： </p>
<p>1）&nbsp; 该业务的使用场景 </p>
<p>2）&nbsp; 业务流程 </p>
<p>3）&nbsp; 该业务与其他业务的关系及交互方式 </p>
<p>4）&nbsp; 该业务的输入输出及业务规则或算法 <br>&nbsp;设计人员 <br>&nbsp;一天 <br>&nbsp;10% <br>&nbsp;<br>简单设计 <br>&nbsp;指明确定义类的名称及所在包的位置，明确定义业务方法的名称及传入传出参数的类型，明确定义XML格式及数据模型。 <br>&nbsp;开发人员 <br>&nbsp;半天 <br>&nbsp;20% <br>&nbsp;<br>迭代版本一 <br>&nbsp;指开发过程中第一次体现在每天发布的最新版本中的实现，达到前后台根据接口定义实现连通，已经完成了junit单元测试程序，但可以不包括具体的业务实现；在此版本实现的过程中，开发人员彻底明确接口的含义，并在连通过程中彻底理解业务逻辑。 <br>&nbsp;测试人员 <br>&nbsp;一天 <br>&nbsp;40% <br>&nbsp;<br>迭代版本二 <br>&nbsp;指在迭代版本一的基础上进一步重构所得到的版本；该版本应该实现具体的业务逻辑，在正常操作的情况下能够完成业务，但在程序健壮性（如各种合法性检查）方面还相对很差。 <br>&nbsp;测试人员 <br>&nbsp;半天 <br>&nbsp;60% <br>&nbsp;<br>迭代版本三 <br>&nbsp;指在迭代版本二的基础上进一步重构所得到的版本；该版本应该在程序健壮性方面加强，增加各种合法性检查、前后业务环节的交互等。 <br>&nbsp;测试人员 <br>&nbsp;半天 <br>&nbsp;80% <br>&nbsp;<br>迭代版本四 <br>&nbsp;对结构进行重构，合理分配类的职责，提炼公用的类及方法等，修改bug。 <br>&nbsp;测试人员 <br>&nbsp;半天 <br>&nbsp;100%<br>&nbsp;</p>
<p><br>配置、版本管理贯串整个过程<br>环境： </p>
<p>&nbsp; 开发环境： </p>
<p>&nbsp; 客户端：rational rose2002、jbuilder10或eclipse30、vss client等 </p>
<p>&nbsp; 应用服务器：weblogic704、ant16、jdk13、junit381、checkstyle、数据库同步脚本 </p>
<p>&nbsp; 数据库服务器：开发专用数据库oracle9i </p>
<p>&nbsp; 配置管理：vss client </p>
<p>&nbsp; 测试环境： </p>
<p>&nbsp; 应用服务器：weblogic704、ant16、jdk13、junit381、checkstyle、数据库同步脚本 </p>
<p>&nbsp; 数据库服务器：测试专用数据库oracle9i </p>
<p>&nbsp; 版本数据库： </p>
<p>&nbsp; 用于数据库脚本抽取 </p>
<p>版本管理： </p>
<p>小发布：开发人员每天提交代码到vss开发库，开发环境每天集成自动发布，提供开发人员及内部测试人员测试。测试后满足需求则成为产品代码。不满足反馈开发人员修正。 </p>
<p>每日创建脚本自动执行以下功能： </p>
<p>&nbsp; vss打标签，以便以后可以取到每天的版本 </p>
<p>&nbsp; 自动运行junit测试程序并生成测试报告 </p>
<p>&nbsp; 自动运行编码规范检查并生成报告 </p>
<p>&nbsp; 自动生成ormap </p>
<p>&nbsp; 自动编译部署 </p>
<p>&nbsp; 自动完成抽取数据库脚本并迁入vss </p>
<p>大发布：根据发布计划，每周（假定）发布测试版本提供集成、验收测试，最好是客户人员测试。通过一套自动发布脚本完成。配置人员负责组织、汇总《版本发布说明》<br>&nbsp;<br>相关规范及模板<br>请参考配置库中相关规范及模板 </p>
<p>&nbsp; ant发布脚本 </p>
<p>&nbsp; 数据库版本同步脚本 </p>
<p>&nbsp; 编码规范 </p>
<p>&nbsp; 代码格式检查模板xml </p>
<p>&nbsp; 分析设计模板 </p>
<p>&nbsp; 项目执行规范 </p>
<p>&nbsp; 《版本发布增量说明_20040916_发布人》 </p>
<p>&nbsp; butterfly问题流转规范 </p>
<p>&nbsp; 数据库开发活动管理规范 </p>
<p>&nbsp; 其他 </p>
<p>&nbsp; <br></p>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/28612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2007-06-17 13:00 <a href="http://www.cnitblog.com/MartinYao/articles/28612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>迭代开发的新思想</title><link>http://www.cnitblog.com/MartinYao/articles/28611.html</link><dc:creator>玄铁剑</dc:creator><author>玄铁剑</author><pubDate>Sun, 17 Jun 2007 04:58:00 GMT</pubDate><guid>http://www.cnitblog.com/MartinYao/articles/28611.html</guid><wfw:comment>http://www.cnitblog.com/MartinYao/comments/28611.html</wfw:comment><comments>http://www.cnitblog.com/MartinYao/articles/28611.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/MartinYao/comments/commentRss/28611.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/MartinYao/services/trackbacks/28611.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<p>Per Kroll<br>Director，Rational Unified Process IBM<br>2004年4月 </p>
<p><br>本文来自 Rational Edge ：RUP 的专家解释了被软件开发项目成员需要的职责和观点上的改变，并且介绍了成功的从传统的瀑布型方法向迭代方法转变的客户案例。<br>成功的采用迭代开发方法的实践不仅仅需要部署一系列的新技术，也需要改变团队协作的方式和团队成员的职责。在本文中，我们将会了解到被软件开发项目成员需要的职责和观点上的改变，并且介绍了成功的从传统的瀑布型方法向迭代方法转变的客户案例。</p>
<p>广泛的引用这些变化作为一种&#8220;新的思想&#8221;，我们将关注软件开发项目中的不同个体角色： </p>
<p>分析人员 主要负责与客户交互和需求。 <br>开发人员 主要负责设计、实现和单元测试。 <br>测试人员主要负责功能、性能和系统测试。 <br>项目经理 主要负责持续的项目团队的跟踪并关注关键的交付产物。 <br>质量保证和方法专家 负责质量标准和最佳实践。 <br>客户 负责澄清他们的业务需求关心什么样的能力。&nbsp; </p>
<p><br>分析人员的新思想<br>在传统的瀑布型的方法中，分析人员与用户和项目团队之外的涉众打交道。目标是理解并开发一个代表了一系列需求的方案，文档化这些需求然后将这些需求文档交给开发团队。一些开发组织用一种&#8220;未来&#8221;状态的长列表来详细说明需求；另一些组织在高层次上表达需求，为解释需求保留了很大的空间。在这两种情况下，必须有这样的假设，分析人员既要了解业务又要了解用户，并且这个分析人员应该是指定系统应该具有什么功能的人。</p>
<p>一旦分析人员文档化了需求，他或者她就会要求用户来检查这些需求文档（甚至如果他们不能完全理解用来表达需求的技术语言，并且/或者他们不能通过可视化的方法来表示当系统被实现时许多需求是如何满足用户的需要的）。然后，实现需求规格说明就是开发人员的工作了。典型的，不论是开发人员还是测试人员都没有参与到阐述需求的工作中。并且一旦需求被规格化，很少会有在分析人员与设计人员之间的积极的交互。分析人员只是简单的阐明需求说明书中包含的内容。</p>
<p>这种传统的模型在某些方面的缺陷将在下面被解释。&nbsp; </p>
<p>&nbsp;</p>
<p>分析人员的新思想</p>
<p><br>建立与最终客户的持续的交互以确保开发人员可以创建正确的系统。 <br>鼓励尽早的开发和实现系统的关键能力部分，以加深你对什么需求将满足业务需要的理解。 <br>从一开始就与开发人员和测试人员一起优化序需求。 <br>为需求选择适当的详细程度，可以根据你的项目和当前的生命周期阶段而定。&nbsp; </p>
<p>&nbsp;</p>
<p>分析人员不应该孤立的指定需求<br>首先， 瀑布型的方法失败的认识到客户、开发人员和测试人员参与需求说明工作的价值。没有对业务和技术拥有优秀的理解将不可能创建出能够改进你的业务的软件系统。不幸的是，很少有人同时在业务和技术领域具有深厚的知识背景。这就意味着，分析人员、开发人员、测试人员和客户应该一起工作提供需要的所有的信息以确保开发人员可以创建&#8220;正确的&#8221;软件系统 — 也就是说，一个充分满足客户业务需要并且提供从根本上有效的改进客户业务的能力的软件。</p>
<p>让我们来看一个简单的例子以说明这样的团队协作的好处。&nbsp; </p>
<p><br>例子：基于 Web 的航班预约系统</p>
<p>我们假设一个分析人员负责对这个基于 Web 的自助服务的航班预约系统的需求工作。这个分析人员指定用户将提供一个航班的代码并指明行程的开始地和目的地。如果用户不知道航班代码，他们可以通过提供城市名字进行查询。然后，这个分析人员指定，在用户预定了一个指定的航班后，他们将会得到关于如何联系不同的代理以预约到达目的地时的地面交通工具。</p>
<p>当设计人员检查系统需求时，他回想起曾经看到过一个能够提供部分功能的并且经过证明的Web 服务的方案。这个低成本的服务允许用户导航机场的地图显示并快速的找到符合他们需要的机场，甚至假如用户不熟悉他们的目的地城市或者不熟悉目的地的地区的机场。</p>
<p>在与客户验证了策略后，分析人员和设计人员对需求作了改动以包含这个 Web 服务的实现。然后，在几天的开发工作后，设计人员发现了这个服务的另一特性：当用户选择了一个机场时，他们会自动的收到一个机场信息的列表，信息中包括可得到的地面交通工具的模式和对每种模式预定的容量。设计人员和分析人员与客户和项目经理讨论了这个发现，大家都同意合并这个额外的 Web 服务的特性到他们的新系统中，代替他们原来指定的创建一个地面交通引用的特性。</p>
<p>就像你从这个简单的例子中所看到的那样，在项目的早期阶段就让设计人员/开发人员参与到需求中能够带来巨大的好处。他们中的每一个人都可以建议分析人员或者最终用户考虑不到的能力和方案。当然，衡量预期的项目范围变化的价值仍然是项目经理和客户的责任，分析人员仍然必须理解业务需要并驱使系统应该在何处结束。但是他或她可以通过与设计人员/开发人员协作找到更好的方案。</p>
<p>分析人员和最终用户的交流应该贯穿于整个项目的生命周期中<br>传统开发模式的另外一个缺陷是缺乏在分析人员与最终用户之间的交流。 最终用户被期望预先的指出需求并且对需求进行检查，但是他们有限的参与了方案的开发。在许多情况下，和约的商定是以预先被描述的需求为基础的，并且后来的变更需要有一个和约上的协商。</p>
<p>在整个开发的生命周期中维护在用户与分析人员之间的交流是尤其有效的。双方都应该理解他们拥有相同的目标：建立满足质量要求的可以解决问题的方案，同时成本是可接受的。如果他们的关系是围绕着争论关于什么是以前达成的一致和谁应该为此付钱，而不是建立一个正确的方案的话，那么项目就陷入了麻烦之中。这并不意味着分析人员应该接受所有的需求或者最终用户不应该作出变更的请求。相反，这意味着所有的项目相关的人员应该在提出需求和最终进入到订单中的需求进行一个平衡以形成更好方案的开发。他们需要认可当他们过分的严格时，应该通过一些讨论以达到一个折中的方案，并且要作积极的改变以保持项目按照计划进行。当然，这一点做起来要比说的有难度。但是朝着有效的团队协作的第一步是在分析人员与最终用户之间建立起有建设性的对话。</p>
<p>过度的指出预想的需求是不明智的<br>传统的开发方法提倡详细的预先需求，并且在过去的多年里很多人觉得项目失败是因为他们的需求对启动项目是不够详细的。但是增加需求说明的详细程度将会减少的回报。在一些情况下，项目团队需要不断的构建方案，并假设需求在整个项目周期不断的改进。记住：软件项目的主要目标是在尽可能低成本的条件下生成可执行的能够解决手工形式的业务问题的代码。一旦你的需求到达了一定的细化程度，将他们定案的最廉价的方法是对系统进行部分的实现以可以向最终用户进行演示。同时你可以一起确定你还需要提供什么样的其他能力。定案需求通常要经过几次的迭代，在迭代期间你可以调整需求、设计和代码，然后对测试进行引导。</p>
<p>在项目周期的后期你可以不必正式的文档化很多的详细的需求；代码本身可以提供足够的文档，并且很少在团队中误解什么是需要实现方面存在风险。这依赖于正被开发的系统自然的改变了参与的人数、系统期望的生命跨度、和约的义务和附加的质量标准的需求。最后，也许是最重要的，你应该象驱赶技术风险一样在项目中尽早驱赶商业上的风险。在细化预想的需求上花费过多的时间会使你的注意偏离出降低关键的风险。 </p>
<p>&nbsp;</p>
<p>开发人员的新思想</p>
<p><br>扩大了的职责包括详细设计、实现和单元测试。 <br>成为需求工作中的一部分：帮助阐明需求然后创建符合需求的方案。 <br>成为了测试工作的一部分：按照测试先行的设计原则开发代码。 <br>尽可能的重用已存在的方案而不是重新构建方案。&nbsp; </p>
<p>&nbsp;</p>
<p>开发人员的新思想 </p>
<p><br>迭代开发，对开发人员来说使用与迭代开发相关联的最佳实践和现代的工具技术，同样需要在思想上的转变。首先，就像我们在上一部分讨论的，开发人员需要在指定需求中扮演更多积极的角色。</p>
<p>过去，开发人员以对辣手的问题提出聪明的解决方法为荣。他们创造唯一的方案以使系统性能最大化、内存使用最小化或者提供良好的图形用户界面。当然，开发人员仍然需要提出聪明的方法，但是他们的精力需要从构建方法转向到发现聪明的方法以尽量的将可重用的资产、开发源码的软件、通用的商业现货 (COTS) 组件和 Web 服务集成成为一个可使用的方案。为了成为优秀的开发人员，你需要知道如何最好的利用交互式的开发环境（IDE）和建模环境。&#8220;这里没有发明&#8221;的态度是达不到预期的目标的；作为一个开发人员，你的精力应该放在通过利用各种可重用的资产来产生可使用的方案上。今天快速并廉价的生产出高质量的产品才是应该受到褒奖的。</p>
<p>质量是测试团队的职责。在传统的开发中，在项目的最后几周，整个系统才交付到可怜数量的测试人员手中，他们被要求尽可能多的找出软件系统的缺陷。他们负责质量，开发人员负责修改他们发现的缺陷。迭代开发正好与之相反，迭代开发认为质量是项目中每一个人的职责。现在我们拥有支持这种共有职责概念的工具和过程，允许我们交付高质量的代码。新的工具技术允许我们同步代码和设计。他们也使我们可以在系统被完成前测试代码产生的内存泄漏问题和性能问题，这是在过去无法达到的。现代的配置管理和变更管理环境支持了每日构建，不仅允许我们测试我们分离的代码，还允许我们测试我们的代码如何与系统的其他部分代码的集成。</p>
<p>现代的最佳实践包括测试先行的设计：首先你要指出你应该进行什么测试，然后再构建能够通过这些测试的软件。这样创建高质量的代码是我们重点要考虑的事情。现代的工具技术也支持设计的质量问题，1 它使质量成为了设计过程中的主要部分。它允许你在设计过程的早期就进行质量的测量并且可以自动的从设计模型中产生测试。通过保证设计的质量增强了整个系统的质量并保证了测试代码的完成。</p>
<p>总而言之，使用迭代式的开发方法，开发人员角色需要进行扩展；除了简单的实现需求规格说明，开发人员必须在决定什么对整个系统是必要的方面承担更多的任务。这包括帮助确保需求是正确的和在可接受的成本下创建出高质量的系统。为了作出最好的决定，开发人员需要更好的理解项目的远景和驱动项目的业务问题。这样开发人员才有可能创建一个满足需求和能够解决业务问题的方案。 </p>
<p>&nbsp;</p>
<p>测试人员的新思想</p>
<p><br>成为团队中在质量问题上的指导者。 <br>与分析人员和开发人员一起工作以确保需求和设计是可测试的。 <br>在项目的早期就应引入测试。 <br>稳定能力的持续的自动化测试。&nbsp; </p>
<p>&nbsp;</p>
<p>测试人员的新思想 </p>
<p>过去，我们注意到按照传统的方法，当项目快要结束时，开发出来的软件才被交给测试人员，让测试人员通过找到软件的缺陷来为软件&#8220;注入质量&#8221;。每一个测试人员都可能会退缩，因为通过经验他们知道这种方法是多么没有效率和令人失望的。</p>
<p>使用迭代的开发方法，测试人员仍然要负责确定系统的质量是否足以发布，但是他们确保完成高质量系统的方法却从根本上发生了变化。首先，测试人员在项目非常早的时候就参与其中，因为每一个迭代（可能除了第一个迭代）都会产生可以被立即测试的可执行的结果。在项目早期，测试更关注找到&#8220;影响大的&#8221;问题，而不是验证代码是不是已经可以交付了。这就意味着你不能简单的将代码交给测试人员；相反，测试人员需要与分析人员和开发人员密切的合作以便他们能够理解在每个迭代中什么是需要被测试的。</p>
<p>此外，测试人员必须向团队的其他能够适当的改经需求、设计、代码和其他支持性的产物的成员提供测试的反馈。测试人员可以通过这些任务来帮助其他项目成员的工作：通常他们可以帮助产生更好的需求，因为他们在计划方法来测量一个需求是否被满足的方面是经过训练的。同时，现代的集成测试和开发环境允许他们通过使用基线的代码配置进行连续的测试工作。</p>
<p>就像分析人员和开发人员承担了更多的任务一样，测试人员也承担起了更多的任务。在项目周期的后期，测试人员作为质量专家，对整个开发团队提供专家意见。例如，除了执行大量了集成和验收测试之外，他们可以在质量的相关决定上对项目经理进行指导。</p>
<p>因为贯穿整个项目中需求是被迭代的识别、细化、开发和测试的，因此项目团队并不应该过早的生成所有被执行的测试的详细说明。相反，早期的焦点应该是理解对于一定的阶段或者迭代的测试的目标 — 他们应该完成什么。这将焦点移到了识别每个迭代的潜在的问题领域上，并且开发测试以暴露那些问题领域。</p>
<p>迭代开发意味着在项目的早期你就要开发测试系统的关键能力。同时也意味着你需要在后续的迭代中测试和重新测试这些能力以确保你认为应该被解决的问题不会再一次出现。不通过有效的自动化测试进行完全的回归测试是不切合实际的 — 而且通常是不可能的，因此你必须要在整个项目中不断的开发出可自动化的测试。有效的实现这一点的诀窍是理解在迭代不断持续时什么元素是可以保持稳定的；通过这种方法，你可以避免为每一个迭代重写自动化测试。这就要求你对系统的体系架构有一定的了解；在比较靠后的迭代中，测试应该更注重系统详细的功能性。 </p>
<p><br>项目经理的新思想</p>
<p><br>公开项目面临的风险，持续的重新评估风险，并且使用风险来为项目工作进行优先级的划分。 <br>通过衡量可演示的结果而不是一系列被完成的活动来评估项目状态。 <br>在项目的早期，对整个项目开发高层次的计划，但仅仅对当前的和下一个迭代生成详细计划。 <br>根据你如何有效的处理风险的经验，在任何给定的时间上评估你在需求、架构、设计、实现和测试上的投入。 <br>信任你的团队。给他们足够的知识和职责让他们全全负责产品的质量。帮助他们团结在一起工作。&nbsp; </p>
<p>&nbsp;</p>
<p>项目经理的新思想 </p>
<p>迭代开发方法的一个最重要的区别是他被设计成为在项目的早期将主要的风险去除掉。利用这个差别需要对项目所面临的风险公开而且诚实。同时你逃避风险的自然倾向会使人们推迟处理这些风险，风险不知何故的被忽略 — 就像他们从未发生过。风险就像是传染病：你忽略它越久，它的危害就越大。风险必须在整个项目中被持续的识别并划分优先级；每一个迭代都必须被降低风险的原则性的目标所驱动。</p>
<p>使用这种方法会需要一些文化上的变化。典型的管理形式规定你应该对广大听众避免承认风险，因为人们可能会断定你们在运作一个有问题的项目。这是一个危险的方法：假装风险不存在不会使风险离去。</p>
<p>传统的情况下，项目经理通过询问团队成员什么活动已经被完成来确定项目的状态。他们假设但所有活动都被完成时，项目也就被完成了。但是这种方法经常会导致项目的失败。检查被完成的活动是不好的测量项目进度的方法，因为它并没有对活动的结果的质量进行量化。如果项目经理能够精确的计划项目团队需要做的每一项工作，并且没有会背离项目计划的事情发生，这种方法可能会满足项目的需要。然而，就像很多项目经理知道的那样，事情很少是按照计划进行的。甚至是如果你创建了更为详细的计划，结果也是令人惊讶的。无论我们如何努力的预期未来，我们也不能预期每一件事情。</p>
<p>基于结果的管理<br>因为我们不能预测未来，软件项目的经理需要对他们的一些关键的策略进行风险的管理。这需要改变你的测量方法：代替基于完成活动的测量方法，你应该使用基于可演示的结果的方法进行测量。这是基于结果管理的基础。应用基于结果的管理策略意味着将重点放在风险上并正面的处理它。通过特意的结构化项目的活动以处理风险，你可以揭示隐藏的问题，解决问题并稳定的减少项目进程中的不确定因素。</p>
<p>此外，因为一个软件开发项目的主要结果是软件本身，所以你所交付的产物应该是成功的主要量度。你可以使用象一系列被通过的软件测试、代码中的缺陷的数量和他们的精确度等等的矩阵来评估你的软件。换句话说，移到迭代开发就意味着要通过根据指定目标和需求产生的的测量可演示的结果，而不是通过计算有多少活动、产物或者工作产品被完成来评估项目的状态。为了评估项目的稳定性（有效管理的另一个量度），你也应该跟踪需求、设计和代码中的冗余。</p>
<p>更少的也许是更多的<br>早期，我们注意到添加详细的信息到需求也许不总是对项目有益的。对其他类型的文档也是同样的。你的质量保证计划、软件开发计划或者需求管理计划都不是项目健康的良好量度。太详细不总是更好的：你应该调整你特定项目需要的文档详细级别。决定合适详细级别的方法是关注风险和结果：如果你添加详细信息到某一产物可以减少风险或者改进特定结果的质量，那么这个投入是值得的；否则，在更有生产力的活动上花费时间是更好的。</p>
<p>使用瀑布型的方法项目经理需要付出很多的注意以详细的计划和指定需求。而使用迭代开发的方法项目经理可以根据工作中的风险来权衡的将时间花费在细化需求、架构、设计和实现上。他们会问：&#8220;什么样类型的活动可以最有效的立即降低风险呢？&#8221; 也许原型化一个方案可以处理与项目客户买进相关的风险，或者也许他们需要实际的设计、实现和测试架构以完全的处理架构方面的风险。</p>
<p>使项目中的每一个成员都参与到质量保证中<br>对于项目经理来说移到迭代开发方法需要的其他思想的改变是开始将质量保证作为一个集体的职责考虑。我通常会惊讶的听到项目经理说&#8220;我需要测试小组对我的开发人员保持忠诚，&#8221;或者&#8220;如果分析人员没有写下单个的需求，他们将不会被实现。&#8221; 当然，你的确需要测试小组来建立高质量的应用，并且失败的文档化和跟踪需求将导致问题的出现。但是如果开发人员不把质量当作自己的责任，你也就会陷入到质量问题中。为了实现这一点，你需要从通过信任你的团队和清晰的交流你们的预期开始。假如你不能信任这些人，那么也许这些人不应该属于你的团队。</p>
<p>理想的情况下，项目经理应该能够宣称&#8220;我的开发人员负责交付高质量的代码；为了帮助开发人员，我们有一个测试团队，测试团队有专业的能力并可以验证被交付的代码是否是高质量的，&#8221;并且&#8220;我们的开发人员负责实现满足最终用户需要的应用。为了帮助开发人员，我们有一个分析的团队在适当的详细级别上文档化需求，并且分析人员是开发人员和最终客户之间的桥梁。&#8221; 创建交能够协同工作的团队 — 也就是说使团队中的分析人员、开发人员和测试人员能够一起工作来实现高质量的结果 — 是成功的迭代开发的关键之一。 </p>
<p>&nbsp;</p>
<p>质量保证和方法专家的新思想</p>
<p><br>为项目选择适当的形式级别（更多的不总是更好的）。 <br>关注在整个项目周期中维护质量，但是可以是灵活的。最好的到达高质量的做法不是仅仅通过疯狂的关注检查和测试实现的，而是通过在给定时间上对需求、架构、设计、实现、检查和测试的良好平衡实现的。 <br>采用风险驱动的过程方法。你的过程应该允许项目经理对项目当前的风险情况采用战术性的活动。&nbsp; </p>
<p><br>质量保证和方法专家的新思想 </p>
<p>许多组织都有质量专家 — 负责达到一定的标准的人，比如 SEI CMM / CMMI 中的标准，或者是组织内部的质量标准。许多组织也有方法专家，他们或者来自软件工程过程组（SEPG），或者是独立的负责软件开发中的方法。</p>
<p>通常，这些质量和方法专家在采用迭代的开发思想时存在最大的问题。他们中的许多人花费了他们职业生涯的大部分时间来驱使组织按照&#8220;文档越多越好&#8221;、&#8220;越多检查越好&#8221;、&#8220;对于过程工作，需要被彻底的文档化&#8221;，和&#8220;过程应该提供一个基于时间的你所需要执行的项目中的特定任务的描述&#8221;这样的传统的至理名言来指定过程。他们相信通过跟随这些提供了高度形式化的原则，就可以避免项目的失败。</p>
<p>然而，当这样做的太过火时，将产生相反的效果，因为高度的形式化将增加迭代的成本，并鼓励使用瀑布型的周期。相反，你需要通过风险驱动，对每个迭代产生可演示的结果的迭代方法彻底的平衡文档的最佳实践。这种方法允许项目团队增强产品的质量，同时也可以降低形式化的程度和整个的成本。我们应该注意，使用迭代的方法并不排斥使用高度形式化的方法，高度形式化的方法可能对安全第一的应用或者其他严格要求质量的应用是有用的。2 </p>
<p>灵活性是关键的<br>一个关键的变化是软件过程和质量方法应该提供给项目经理调节项目风险的足够的灵活性；项目经理应该不断的监视项目的活动和状态，并且调整过程的执行以降低关键的风险。一个过程可以指明如何应对各种风险和产生被需要的结果，但是风险典型的是预先未知的，因此你不可能在早期就指明什么任务应该被执行来应对风险。你也不知道哪一个需求应该被指定什么时候用什么组件来设计和实现他们。这就意味着你所用的过程需要提供关于里程碑代表什么、如何实现它和如何降低风险的清晰的管理指南 — 通过注意项目执行的细节来保留过程的灵活性。 </p>
<p>你不能通过在项目过程中简单使用具体的指导来创建一个一个有效的项目计划。项目计划本身需要是一个迭代的过程，包括对当前风险、进度、测试结果等等进行评估以为下一阶段的迭代的详细计划收集输入。 </p>
<p>这也意味着项目的检查或者审计不应该主要的关注验证是否项目团队已经制造了一系列的产物或者执行了一系列的活动。相反，审计应该瞄准在识别和验证风险和确认适当的产物和活动被完成以降低风险上。审计也应该检查以前的问题以识别出公共的失败模式，并且建议过程的修改以保护将来的最小失败的可能性。&nbsp; </p>
<p><br>客户的新思想</p>
<p><br>积极的参与描述需求并成为软件开发团队中不可缺少的部分。 <br>对已经被开发的软件的能力不断的提供反馈，比如工作原型和用户界面设计。 <br>利用一种使用迭代方法的进步的获得模式；这种模式保证买家和卖家的双方利益。&nbsp; </p>
<p>&nbsp;</p>
<p>客户的新思想</p>
<p>使用传统的软件开发方法的客户期望在开发工作中有最小的投资。他们想预先指出所有的需求，确定一个固定的价格，然后等待最终系统的交付。经常的，会产生在期望值和实际交付系统之间的非常大的差距 — 解决方案并没有满足客户真实的业务需要。 </p>
<p>通过转向迭代开发，改变客户和开发团队之间的交互模式，客户和开发团队都可以避免大量的痛苦。在一个迭代开发的项目中，客户应该是构建应用团队中的不可缺少的一部分。客户与开发团队的其他成员协同工作以确保最终交付的应用系统满足被需要的业务价值。客户的组织应该尽可能的保持与开发团队之间交互的兴趣，以确保开发团队可以理解他们应该构建什么和项目中具有什么样的风险和问题。如果客户没有帮助指导开发的工作，开发团队可能会开发出错误的应用 — 每个人都会蒙受损失。 </p>
<p>在迭代开发的模式中，客户不能仅仅指出他们所预期的然后就等待系统交付。不论他们怎么清晰的定义，所有的需求都从属于众多的说明和可能的实现。对开发团队来说，与其生成更加详细的需求，还不如投入时间更加频繁和有效的与项目的关键投资人（包括客户）进行沟通。那么，当客户查看演进的应用时，他们将获得应用应该做什么的更好的理解，并可以提供有建设性的建议以改进系统。同时，如果在项目中业务要求发生快速的变化，需求也需要随之发生改变。 </p>
<p>客户也可以从公开协商迭代式的和约中受益，一个叫作累进的获取得方法。使用这个方法，首先双方可以为整个项目协商一个大致的协议作为描述双方管理商业关系的合法的指导。然后项目被划分为两个或者更多的子和约。早期的和约基于时间和所需的资源指明了款额，因为任何一方都不能足以知道整个方案和可能的开发成本以作出合理的预先承诺。后来的和约式固定的价格，它最小化了双方对应该的交付产物的不一致。3&nbsp; </p>
<p>&nbsp;</p>
<p>结论 </p>
<p>我们已经讨论了对软件开发采用迭代的方法不仅仅简单的需要遵循一系列的指南。迭代开发和支持迭代开发的现代技术改变了软件开发游戏中的规则，并使许多在过去战统治地位的公理失去了效力。成功的从瀑布型的方法向迭代的方法转变要求软件开发团队在个人的责任和如何与团队其他成员交互上发生了变化。换句话说，它要求在多中角色团队成员的行为和价值上作出明显的和持久改变。 </p>
<p>只有每一个团队成员都能够理解迭代开发需要做的必要的改变的基本原理，组织才能够实现这些变化。在每一个项目的开始，对于项目团队来说，公开的讨论我们在本文中的迭代开发训练部分已经讨论的必要的行为和有感知的变化是有益处的。本文可以作为这些讨论的出发点：项目团队应该赞同这些思想上的改变和上面针对他们特定项目讨论的实践。 </p>
<p>基本上，本文是关于如何通过使用迭代开发的方法和通过确保整个团队共享项目的远景建立&#8220;正确的&#8221;软件的，并讲述了你应该如何与团队紧密的合作来实现这个远景。项目经理能够在工作过程中鼓励这种变化，但是它最终建立在团队成员接受和有效的实施是些变化之上。&nbsp; </p>
<p><br>鸣谢 <br>我非常的感谢 Kurt Bittner 、Anthony Kesterton 和 Glen Tattersall ，他们对本文进行有价值的校对，同时也感谢 Marlene Ellin 出色的编辑工作。&nbsp; </p>
<p>其他读物 <br></p>
<img src ="http://www.cnitblog.com/MartinYao/aggbug/28611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/MartinYao/" target="_blank">玄铁剑</a> 2007-06-17 12:58 <a href="http://www.cnitblog.com/MartinYao/articles/28611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>