3.1前期准备的重要性
如果在项目末期强调质量,那么你会强调系统测试。
如果在项目中期强调质量,那么强调构建实践。
如果在项目的开始阶段强调质量,那么就会计划,要求并且设计一个高质量的产品。
准备工作的中心目标就是降低风险:一个好的项目规划者能够尽可能早地将主要的风险清除掉,以使项目的大部分工作能够尽可能平稳地进行。目前,软件开发中最常见的项目风险是糟糕的需求分析和糟糕的项目计划,因此准备工作就倾向于集中改进需求分析和项目规划。
准备不周全的诱因
造成准备工作不充分的一个常见原因是:
一,那些分配去做前期准备活动的开发人员并不具备完成这一任务的专业技能。
二,不能抵抗尽快开始编码的欲望。
三,管理者们对那些“花时间进行构建活动的前期准备的程序员”的冷漠已经到了人神共愤的程度。
关于开始构建之前要做前期准备的绝对有力且简明的论据
1.诉诸逻辑
准备工作很重要。
2.诉诸类比
项目都是类似的。
程序员是软件事物链的最后一个环节。架构师吃掉需求,设计师吃掉架构,而程序员则消化设计。
3.诉诸数据
在一开始就把事情做好是最合算的。进行非必要的改动的代价是高昂的。
“发现错误的时间要尽可能接近引入该错误的时间”
引入缺陷的时间 | 需求 | 架 构 | 构建 | 系统测试 | 发布之后 |
需求 | 1 | 3 | 5-10 | 10 | 10-100 |
架构 | 1 | 10 | 15 | 25-100 | |
构建 | 1 | 10 | 10-25 |
3.2辨明你所从事的软件的类型
软件种类
---------------------------------------------------------------------------------------------------------------------------------
商业系统 使命攸关的的系统 性命攸关的嵌入式系统
---------------------------------------------------------------------------------------------------------------------------------
典型应用 internet站点 嵌入式软件 航空软件
intranet站点 游戏 嵌入式软件
库存管理 internet站点 医疗设备
游戏 盒装软件 操作系统
管理信息系统(MIS) 软件工具 盒装软件
工资系统 web services
---------------------------------------------------------------------------------------------------------------------------------
生命周期模型 敏捷开发 分阶段交付 分阶段交付
(极限编程,scrum,time-boox) 渐进交付 螺旋型开发
渐进原型 螺旋型开发 渐进交付
---------------------------------------------------------------------------------------------------------------------------------
计划与管理 增量式项目计划 基本的预先计划 充分的预先计划
随需测试与QA计划 基本的测试计划 充分的测试计划
非正式的变更控制 随需QA计划 充分的QA计划
正式的变更控制 严格的变更控制
---------------------------------------------------------------------------------------------------------------------------------
需求 非形式化的需求规格 半形式化的需求规格 形式化的需求规格
随需的需求评审 形式化的需求检查
---------------------------------------------------------------------------------------------------------------------------------
设计 设计与编码是结合的 架构设计 架构设计
非形式化的详细 形式化的架构检查
设计 形式化的详细设计
随需的设计评审 形式化的详细设计检查
---------------------------------------------------------------------------------------------------------------------------------
构建 结对编程或独立编码 结对编程或独立编码 结对编程或独立编程
非正式的check-in手续 非正式的check-in手续 正式的check-in手续
或没有check-in手续 随需代码评审 正式的代码检查
---------------------------------------------------------------------------------------------------------------------------------
测试与QA 开发者测试自己的代码 开发者测试自己的代码 开发者测试自己的代码
测试先行开发 测试先行开发 测试先行开发
很少或没有测试 单独的测试小组 单独的测试小组
(由单独的测试小组来做) 单独的QA小组
---------------------------------------------------------------------------------------------------------------------------------
部署 非正式的部署过程 正式的部署过程 正式的部署过程
---------------------------------------------------------------------------------------------------------------------------------
迭代开发法对前期准备的影响
迭代开发能够减少前期准备不足造成的负面影响,但是它不能完全消除此影响。
在序列式开发法和迭代式开发法之间做出选择
序列化原因:
1.需求相当稳定
2.设计直截了当,而且理解透彻
3.开发团队对于这一应用领域非常熟悉
4.项目风险小
5.长期可预测性很重要
6.后期改变需求,设计和编码的代价很可能较昂贵
迭代化原因:
1.需求并没有被理解透彻,或者处于其他理由你认为它不是稳定的。
2.设计很复杂,或者有挑战性,或者两者兼具
3.开发团队对于这一个应用领域不熟悉。
4.项目包含许多风险
5.长期可预测性不重要
6.后期改变需求,设计和编码的代价很可能较低。
3.3问题定义的先决条件
在开始构建之前首先要满足的一项先决条件是,对这个系统要解决的问题做出清楚的陈述。
问题定义-》需求-》架构-》构建-》系统测试-》将来改进
3.4需求的先决条件
需求详细描述软件系统应该做什么,这是达成解决方案的第一步。
明确的需求有助于确保是用户驾驭系统的功能。
明确的需求还有助于避免争论。
重视需求有助于减少开始编程开发之后的系统变更情况。
稳定的需求是软件开发的圣杯。
计划严格依照需求行事,实际上就是计划不对客户的要求做出回应。
在购建期间处理需求变更:
1.使用本节末尾的需求核对表来评估你的需求的质量。
2.确保每一个人都知道需求变更的代价。
3.建立一套变更控制程序。
4.使用能适应变更的开发方法。
5.放弃这个项目。
6.注意项目的商业案例。
3.5架构的先决条件
软件架构是软件设计的高层部分,是用于支撑更细节的设计的框架。
架构是适用于整个系统范围的设计约束。
高层设计是适用于子系统层次或多个类的层次上的设计约束
架构的质量决定了系统的“概念完整性”。后者继而决定了系统的最终质量
架构的典型组成部分:
1.程序组织
系统架构首先要以概括的形式对有关系统做一个综述。
在架构中,应该能发现对那些曾经考虑过的最终组织的替代方案的记叙,找到之所以选用最终的组织结构,而不用其他的替代方案的理由。
架构应该定义程序的主要构造块。
应该明确定义各个构造块的责任。
应该明确定义每个构造块的通信规则。
2.主要的类
架构应该详细定义所用的主要的类。
架构应该记述曾经考虑过的其他类设计方案,并给出选用当前的组织结构的理由。
3.数据设计
架构应该描述所用到的主要文件和数据表的设计。
数据通常应该只有一个子系统或一个类直接访问;例外的情况就是透过访问器类或访问器子程序,以受控且抽象的方式来访问数据。
架构应该详细定义所用数据库的高层组织结构和内容。
4.业务规则
如果架构依赖于特定的业务规则,那么它就应该详细描述这些规则,并描述这些规则对系统设计的影响。
5.用户界面设计
用户界面常常在需求阶段进行详细说明。如果没有,就应该在软件架构中进行详细说明。
架构应该模块化,以便在替换为新用户界面时不影响业务规则和程序的输出部分。
6.资源管理
架构应该描述一份管理稀缺资源的计划。
7.安全性
架构应该描述实现设计层面和代码层面的安全性的方法。
8.性能
需求中详细定义性能目标。
性能目标可以包括资源的使用,这时,性能目标也应该详细定义资源之间的优先顺序。
架构应该提供估计的数据,并解释为什么架构师相信能达到性能目标。
9.可伸缩性
可伸缩性是指系统增长以满足未来需求的能力。架构应该描述系统如何应对用户数量,服务器数量,网络节点数量,数据库记录数,数据库记录的长度,交易量等的增长。
10.互用性
11.国际化/本地化
12.输入/输出
架构应该详细定义读取策略是先做,后做还是即时做。
13.错误处理
最棘手的问题。
错误处理是进行纠正还是仅仅进行检测?
错误检测是主动的还是被动的?
程序如何传播错误?
错误消息的处理有什么约定?
如何处理异常?
在程序中,在什么层次上处理错误?
每个类在验证其输入数据的有效性方面需要负何种责任?
是希望用运行环境中内建的错误处理机制,还是想建立自己的一套机制?
14.容错性
架构应该详细定义所期望的容错种类。
容错是增强系统可靠性的一组技术,包括检测错误;如果可能的话从错误中恢复;如果不能从错误中恢复,则包容其不利影响。
15.架构的平行性
架构应该论证系统的技术可行性。
16.过度工程
健壮性是指系统在检测到错误后继续运行的能力。
在软件中,链条的强度不是取决于最薄弱的一环,而是等于所有薄弱环节的乘积。
详细定义一种过度工程的方法尤其重要。
17.关于买还是造的决策
如果架构不采用现货供应的组件,那么就应该说明自己定制的组件应该在那些方面胜过现成的程序库和组件。
18.关于复用的决策
19.变更策略
架构应当清楚地描述处理变更的策略。
架构应该列出已经考虑过的有可能会有所增强的功能,并说明”最有可能增强的功能同样也是最容易实现的“。如果变更很可能出现在输入输出格式,用户交互的风格,需求的处理等方面,那么架构就应该说明:这些变更已经被预料到了,并且任何单一的变更都只会影响少数几个类。架构应对变更的计划可以很简单,比如在数据文件中放入版本号,保留一些供将来使用的字段,或者将文件设计成能够添加新的表格。如果使用了代码生成器,那么架构应该说明,可预见的变更都不会超出该代码生成器的能力范围。
架构应该指出延迟提交所用的策略。
20.架构的总体质量
优秀的架构规格书的特点在于,讨论了系统中的类,讨论了每个类背后的隐藏的信息,讨论了采纳或排斥所有可能的设计替代方案的根本理由。
架构应该是带有少许特别附加物的精炼且完整的概念体系。
每一项变更都应该干净地融入整体概念。
架构的目标应该清楚的表述。
架构应该描述所有主要决策的动机。
优秀的软件架构很大程度上是与机器和编码语言无关的。
架构应该踏在对系统欠描述和过度描述之间的那条分界线上。
架构应该明确地指出有风险的区域。
架构应该包含多个视角。
不应该担忧架构的任何部分。
3.6花费在前期准备上的时间长度