第3章 Measure Twice, Cut Once:Upstream Prerequisities 三思而后行:前期准备
- 3.4 需求的先决条件
- 3.5 架构的先决条件
- 3.6 花在前期准备上的时间长度
- 要点
3.4 Requirements Prerequisite 需求的先决条件
软件架构(software architecture)是软件设计的高层部分,是用于支撑更细节的设计的框架。
为什么要把架构作为前期准备工作呢?因为架构的质量决定了系统的“概念完整性”。后者继而决定了系统的最终质量。一个经过慎重考虑的架构为“从顶层到底层维护系统的概念完整性”提供了必备的结构和体系,它为程序员提供了指引——其细节程度与程序员的技能和手边的工作相配。它将工作分为几个部分,使多个开发者或多个开发团队可以独立工作。
“需求”详细描述软件系统应该做什么?这是达成解决方案的第一步。
3.4.1 Why Have Official Requirements 为什么要有正式的需求
要求一套明确的需求,这点很重要,理由很多。
明确的需求有助于确保用户(而不是程序员)驾驭系统的功能。如果需求明确,那么用户就可以自行评审,并进行审核。否则,程序员就常常会在编程期间自行决定需求。明确的需求免得你去猜测用户想要什么。
明确的需求还有助于避免争论。在开始编程之前,先把系统的范围(scope)确定下来。如果你和另外一个程序员对于“程序应该做什么”意见不一致,你们可以查看书面的需求,以解决分歧。
重视需求有助于减少开始编程开发之后的系统变更情况。如果你在编码过程中,发现了一个代码上的错误,你只需要修改几行的代码,然后就能继续工作。但是如果你在编码的时候发现了一个需求错误,那么你就得改变设计,使之符合更改后的需求。你可能要扔掉部分旧的设计,并且因为要与已经写好的代码相适应,可能导致新的设计,与在项目之初的设计相比,花费更长的时间。此外,还需要废弃那些受此次需求变更影响的代码和测试用例,还需要编写新的代码和测试用例。即便是未受需求变更影响的代码也需要重新测试,以确保其他地方的改变没有引入任何新的错误
需求错误,带来的成本是非常高的。如图3-1报告的那样。
充分详尽地描述(specify)需求,是项目成功的关键,它甚至很可能比有效的构建技术更重要(见图3-6)。
3.4.2 The Myth of Stable Requirements 稳定需求的神话
一旦需求稳定,项目就能以有序的,可预测的,平稳的方式,完成从架构设到设计到编码到测试等一系列工作。
"一旦客户接受了一份需求文档, 就再也不做更改"是一个美好的愿望。然而对一个典型的项目来说,在编写代码之前,客户无法可靠地描述他们想要的是什么。开发过程能够帮助客户更好地理解自己的需求,这是需求变更的主要来源。计划严格依照需求行事,实际上就是计划不对客户的要求做出回应。你应该采取一些步骤来使变更的负面影响最小化。
3.4.3 Handling Requirements Changes During Construction 在构建期间处理需求变更
在构建期间,要更好地应对需求变更,有以下一些可以采用的方式。
使用本节末尾的需求核对表来评估你的需求质量 如果你的需求不够好,那么就停止工作,退回去,先把它做好,再继续前进。当然,因为在此期间你会停止编码,所以感觉似乎会落后。不过,假设你正开车从芝加哥到洛杉矶,突然看到纽约的路牌,那么停下来查看路线图是浪费时间?当然不是,如果没有对准正确的方向,那就要停下来检查一下路线。
确保每一个人都知道需求变更的代价 客户只想到一个新功能就会很兴奋。在兴奋时血液会涌向大脑,人会晕头晕闹,他会把所你们开过的讨论需求的会议、签字仪式,以及已经完成的需求文档抛诸脑后。最简单的对付这种新功能中毒症患者的方式是:“咦,这听起来是一个很不错的注意。不过由于它不是需求文档里的内容,我会整理一份修订过的进度表和成本估计表,这样你可以决定是现在事实,还是过一阵子再说。”“进度”和“成本”这两个字眼比咖啡和洗冷水澡都要提神,许多“必须要有/must haves”很快会变成“有就最好/nice to haves”。
建立一套变更控制程序 如果你的客户激情不减,那就要考虑建立一个正式的变更控制委员会,评审提交上来的更改方案。客户改变他们的想法,认识到他们需要更多的功能,这不是坏事。问题是他们提出更改方案太频繁了,让你跟不上进度。如果有一套固定的变更控制程序,那么大家都会很愉快——你知道自己只需在特定时候处理变更;而客户知道你打算处理他们的提议。
使用能使用变更的开发方法 某些开发方法让你“对需求变更做出响应”的能力最大化。演讲原型(evolutionary prototyping)法能让你在投入全部精力建造系统之前,先探索系统的需求。演进交付(evolutionary delivery)是一种分阶段交付系统的方法。你可以建造一小块、从用户获得一点反馈、调整一点设计、做少量改动,再多建造一小块。关键在于缩短开发周期,以便更块地响应用户的要求。
放弃这个项目 如果需求特别糟糕,或者极不稳定,而上面的建议没有一条能奏效,那就取消这个项目。即使你无法真的取消这个项目,也设想一下取消它之后会是怎样的情况。在取消它之前想想它可能会变得多糟糕。假如在某种情况下你可以放弃这个项目,那么至少也要问问自己,目前的情况和你所设想的那种情况有多大的距离。
注意项目的商业案例 在提到实施这个项目的商业理由的时候,许多需求事项就会从你眼前消失。有些需求作为功能来看是不错的想法,但是当你评估“增加的商业价值”时就会觉得它是个糟糕了的主意。那些记得“考虑自己的决定所带来的商业影响”的程序的身价与黄金相当——不过我更乐意为此建议获得现金报酬
3.4.4 Checklist:Requirements 核对表:需求
针对功能需求
针对非功能需求(质量需求)
需求的完备性
3.5 Architecture Prerequisite 架构的先决条件
3.5.1 Typical Architectural Components 架构的典型组成部分
Program Organization 程序组织
Main Classes 主要的类
Data Design 数据设计
Business Rules 业务规则
User Interface Design 用户界面设计
Resource Management 资源管理
Security 安全性
Performance 性能
Scalability 可伸缩性
Interoperability 互用性
Internationlization/Localization 国际化/本地化
Input/Output 输入输出
Error Processing 错误处理
Fault Tolerance 容错性
Architectural Feasibility 架构的可行性
Overengineering 过度工作
Buy-vs-Build Decisions 关于“买”还是“造”的决策
Reuse Decisions 关于复用的决策
Change Strategy 变更策略
General Architectural Quality 机构的总体质量
3.5.2 Checklist:Architecture 架构核对表:架构
针对各架构主题
架构的总体质量
Amount of Time to Spend on Upstream Prerequisities 花费在前期准备上时间的长度
花费在问题定义、需求分析、架构上的时间,依据项目的需要而变化。一般说来,一个运作良好的项目会在需求、架构以及其他前期时间方面突入10%~20%的工作量和20%~30%的时间。这些数字不包括详细设计的时间——那是构建活动的一部分。
3.6.1 Checklist:Upstream Prerequisites 核对表:前期准备
你是否辨明自己所从事的软件的类型,并对所应用的开发方法做出相应的剪裁?
是否充分明确地定义了需求?而且需求足够稳定,能开始构建了?(详见需求核对表)
是否充分明确地定义了架构,以便开始构建?(详见架构核对表)
Key Points 要点
构建活动的准备工作的根本目标在于降低风险。要确认你的准备活动是在降低风险,而非增加风险。
如果你想开发高质量的软件,软件开发过程必须至始至终关注质量。在项目初期关注质量,对产品质量的正面影响比在项目末期关注质量的影响要大。
程序员的一部分工作是教育老板和合作者,告诉他们软件开发过程,包括在开始编程之前进行充分准备的重要性。
你所从事的软件项目的类型对构建活动的前期准备有重大影响——许多项目应该是高度迭代式的,某些应该是序列式的
如果没有明确的问题定义,那么你可能会在构建期间解决错误的问题。
如果没有做完良好的需求分析工作,你可能没能察觉待解决的问题的重要细节。如果需求变更发生在构建之后的阶段,其代价是"在项目早起更改需求"的20至100倍。因此在开始编程之前,你要确认“需求”已经到位了。
理解项目的前期准备所采用的方法,并相应地选择构建方法。
代码大全
2014-09-12