前期准备 - 三思而后行
1. 前期准备的重要性
准备工作的中心目标是降低风险尽可能早的将主要的风险清除掉,以使项目能平稳进行。软件开发最常见的风险就是糟糕的需求分析和糟糕的项目计划,因此准备工作就倾向于集中改进需求分析和羡慕计划。
准备不周全的诱因:
专业程序元不清楚准备工作的重要性,或者不具备去做前期准备活动的专业技能,或是因为不能抵抗“尽快开始编码”的欲望,或是管理者们对那些“花时间进行构建活动的前期准备的程序员”的冷漠。
发现错误的时间要尽可能接近引入该错误的时间。
2. 辨明所从事的软件的类型
|
使命攸关的系统 |
性命攸关的嵌入式系统 |
|
典型应用 |
Internet站点 Intranet站点 库存管理 游戏 管理信息系统(MIS) 工资系统 |
嵌入式软件 游戏 Internet站点 盒装软件 软件工具 Web services |
航空软件 嵌入式软件 医疗设备 操作系统 盒装软件 |
生命周期模型 |
敏捷开发(极限编程、 Scrum、time-box 开发等等) 渐进原型(prototyping) |
分阶段交付 渐进交付 螺旋型开发 |
分阶段交付 螺旋型开发 渐进交付 |
计划与管理 |
增量式项目计划 随需测试与QA计划 非正式的变更控制 |
基本的预先计划 基本的测试计划 随需QA计划 正式的变更控制 |
充分的预先计划 充分的测试计划 充分的QA计划 严格的变更控制 |
需求 |
非形式化的需求规格 |
半形式化的需求规格 随需的需求评审 |
形式化的需求规格 形式化的需求检查 |
设计 |
设计与编码是结合的 |
架构设计 非形式化的详细设计 随需的设计评审 |
架构设计 形式化的架构检查 形式化的详细设计 形式化的详细设计检查 |
构建 |
结对编程或独立编码 非正式的check-in手续 |
结对编程或独立编码 非正式的check-in手续 随需代码评审 |
结对编程或独立编码 正式的check-in手续 正式的代码检查 |
测试与QA |
开发者测试自己的代码 测试先行开发 很少或没有测试(由单独的测试小组来做) |
开发者测试自己的代码 测试先行开发 单独的测试小组 |
开发者测试自己的代码 测试先行开发 单独的测试小组 单独的QA小组 |
部署 |
非正式的部署过程 |
正式的部署过程 |
正式的部署过程 |
选择更加序列化的方法的原因:
需求相当稳定
设计直截了当,而且理解透彻
开发团队对于这一领域非常熟悉
项目的风险很小
“长期可预测性” 很重要
后期改变需求、设计和编码的代价可能比较昂贵
选择更加迭代的方法的原因:
需求并没有被理解的很透彻,或者出于其它理由认为它是不稳定的
设计很复杂,或者有挑战性,或者两者兼具
开发团队对于这一应用领域不熟悉
项目包含许多风险
“长期可预测性”不重要
后期改变需求、设计和编码的代码很可能较低
3. 问题定义的先决条件
开始构建之前,首先要满足一项先决条件是,对这个系统要解决的问题做出清楚的陈述。这有时称为“产品设想/product vision”、“人物陈述/mission statement” 或者“产品定义/product definition”,“问题定义/problem definition”。
问题定义应该用客户的语言来书写,而且应该从客户的角度来描述问题。
4. 需求的先决条件
要求一套明确的需求,明确的需求有助于确保是用户驾驭系统的功能。有助于避免争论。有助于减少开始编码后系统变更的情况。
衡量需求做得如何:
针对功能需求
是否详细定义了系统的全部输入,包括其来源、精度、取值范围、出现频率等?
是否详细定义了系统的全部输出,包括目的地、精度、取值范围、出现频率、格式等?
是否详细定义了所有输出格式(Web页面、报表,等等)?
是否详细定义了所有硬件及软件的外部接口?
是否详细定义了全部外部通信接口,包括握手协议、纠错协议、通信协议等?
是否列出了用户想要做的全部事情?
是否详细定义了每个任务所用的数据,以及每个任务得到的数据?
针对非功能需求(质量需求)
是否为全部必要的操作,从用户的视角,详细描述了期望响应时间?
是否详细描述了其他与计时有关的考虑,例如处理时间、数据传输率、系统吞吐量?
是否详细定义了安全级别?
是否详细定义了可靠性,包括软件失灵的后果、发生故障时需要保护的至关重要的信息、错误检测与恢复的策略等?
是否详细定义了机器内存和剩余磁盘空间的最小值?
是否详细定义了系统的可维护性,包括适应特定功能的变更、操作环境的变更、与其他软件的接口的变更能力?
是否包含对“成功”的定义?“失败”的定义呢?
需求的质量
需求使用用户的语言书写的吗?用户也这么认为吗?
每条需求都不与其他需求冲突吗?
是否详细定义了相互竞争的特性之间的权衡——例如,健壮性与正确性之间的权衡?
是否避免在需求中规定设计(方案)?
需求是否在详细程度上保持相当一致的水平?有些需求应该更详细地描述吗?有些需求应该更粗略地描述吗?
需求是否足够清晰,即使转交给一个独立的小组去构建,他们也能理解吗?开发者也这么想吗?
每个条款都与待解决的问题及其解决方案相关吗?能从每个条款上溯到他在问题与中对应的根源吗?
是否每条需求都是可测试的?是否可能进行独立的测试,以检验满不满足各项需求?
是否详细描述了所有可能的对需求的改动,包括各项改动的可能性?
需求的完备性
对于在开始开发之前无法获得的信息,是否详细描述了信息不完全的区域?
需求的完备度是否能达到这种程度:如果产品满足所有需求,那么它就是可接受的?
你对全部需求都感到很舒服吗?你是否已经去掉了那些不可能实现的需求——那些只是为了安抚客户和老板的东西?
衡量架构做得如何:
针对个架构主题
程序的整体组织结构是否清晰?是否包含一个良好的架构全局观(及其理由)?
是否明确定义了主要的构造块(包括每个构造块的职责范围及其他构造块的接口)?
是否明显涵盖了“需求”中列出的所有功能(每个功能对应的构造块不太多也不太少)?
是否描述并论证了那些最关键的类?
是否描述并论证了数据设计?
是否详细定义了数据库的组织结构和内容?
是否指出了所用的关键的业务规则,并描述其对系统的影响?
是否描述了用户界面设计的策略?
是否将用户界面模块化,使界面的变更不会影响程序其余部分?
是否描述并论证了处理I/O的策略?
是否估算了稀缺资源(如现程、数据库连接、句柄、网络带宽等)的使用量,是否描
述并论证了资源管理的策略?
是否描述了架构的安全需求?
架构是否为每个类、每个子系统、或每个功能域(functionality area)提出空间与时间预算?
架构是否描述了如何达到可伸缩性?
架构是否关注互操作性?
是否描述了国际化/本地化的策略?
是否提供了一套内聚的错误处理策略?
是否规定了容错的办法(如果需要)?
是否证实了系统各个部分的技术可行性?
是否详细描述了过度工程的方法?
是否包含了必要的“买 vs. 造”的决策?
架构是否描述了如何加工被复用的代码,使之符合其他架构目标?
是否将架构设计得能够适应很可能出现的变更?
架构的总体质量
架构是否解决了全部需求?
有没有哪个部分是“过度设计”或“欠设计”?
整个架构是否在概念上协调一致?
顶层设计是否独立于用作实现它的机器和语言?
是否说明了所有主要的决策的动机?