第三章 软件创建的先决条件
3.1 先决条件重要性
任何只要是有步骤的事情,步骤之间就是有关系的,前面的步骤一定会对后面的步骤有或多或少的影响,软件开发也是一样。
问题定义影响需求分析,需求分析影响设计,设计影响编码。。。
一个高质量的程序员应该在创建过程的开始,中间和末尾都强调高质量。
3.2 问题定义先决条件
问题定义应该在需求分析之前进行。
问题定义应该从用户的角度进行,使用用户的语言进行定义,不应该使用计算机的术语来定义。因为有些问题用程序并不是最好的解决方法。
当然对于与计算机本身有关的问题就另当别论了,比如编程工具出问题。
3.3 需求分析先决条件
明确的需求可以保证是由用户而不是程序员决定系统的功能。
实际开发中,需求是不可能一成不变的,那么如何应对需求的变化呢:
· 让每个人都知道由于变化需求所付出的代价
· 建立一套更改控制过程
· 用开发的方法来容纳变动(例如原型方法,渐进方法)
· 放弃项目(不得已而为之)
书中还对需求分析是否成熟可靠提供了一份检查表,如下:
需求内容
· 系统的所有输入都定义了吗?包括它们的来源、精度、取值范围和频率?
· 系统所有的输出都定义了吗?包括它们的目标、精度、取值范围、频率和格式?
· 所有的报告格式都定义了吗?
· 所有的硬件与软件接口都定义了吗?
· 所有的通信界面都定义了吗?包括握手、错误检查以及通信约定?
· 是否从用户的观点出发,定义了所有必要操作的反应时间?
· 是否定义了时间问题,如处理时间、数据传输率以及系统吞吐能力?
· 是否对用户所要求完成的任务都作出了规定?
· 每项任务所需用到和产生的数据都规定了吗?
· 规定保密级别了吗?
· 规定可靠性了吗?包括软件出错的后果、在出错时要保护的至关重要的信息、以及错误测试和恢复策略。
· 规定所需最大内存了吗?
· 所需最大存储容量规定了吗?
· 对系统的维护性是否作出了规定?包括系统对运行环境、精度、性能以其与其它软件的接口等方面变化的适应能力规定了吗?
· 是否规定了相互冲突的设计之间的折衷原则,例如,在坚固性与准确性之间如何进行折衷?
· 是否制定了系统成败的标准?
关于需求的完善性
· 在开发开始前暂时得不到的信息是什么?是否规定了不够完善的区域?
· 需求定义是否已经完善到了可以成为软件标准的地步?
· 需求中是否有哪一部分令你感到不安?有没有根本不可能实现,而仅仅为了取悦老板和用户才加进来的内容?
关于需求的质量
· 需求是否是用用户的语言制定的?用户也这样认为吗?
· 需求中是否每一条之间都尽量避免冲突?
· 需求中是否注意了避免规定设计工作?
· 需求在详细程度方面是否保持了一致性;有没有应该更详细些的需求?有没有应该更简略些的?
· 需求是否明确得可以分为一些独立的可执行部分,而每一部分又都很明了?
· 是否每一条都与问题和答案相关?是否每一条都可以追溯到产生它的环境中?
· 是否每一条需求都可以作为测试依据?是否可以针对每一条进行独立测试以确定是否满足需求?
· 是否对可能的改动作出了规定?包括每一改动的可能性?
3.4 结构设计先决条件
3.4.1 典型的结构要素
· 程序的组织形式
· 变动策略
· 购买而不是建造的决定
· 主要的数据结构
· 关键算法
· 主要对象
· 通用功能(用户界面,输入/输出,内存管理,字符串存储)
· 错误处理
错误处理很复杂,需要考虑如下问题:
错误处理是纠正还是仅仅测试错误?
错误测试是主动的还是被动的?
程序是怎样对付错误的?
处理错误信息的约定是什么呢
在程序中,应该在哪一个层次上处理错误呢?
每一个模块检验输入数据合法性的责任级别有多高?是每一模块仅检验它自己的数
据,还是由一级模块来检验整个系统的数据?是否每个层次上的模块都可以假定输入其中的数据是合法的?
· 坚固性
裕度设计(over-engineering)
断言(assertions)。
容错性(fault tolerance)。
· 性能(速度和内存)
3.4.2 检查表
· 软件的总体组织形式是否清晰明了?包括对于结构设计的总体评论与描述。
· 模块定义是否清楚?包括它们的功能及其与其它模块的接口。
· 需求定义中所提出的所有功能,是否有恰当数量的模块覆盖?
· 结构设计是否考虑了可能的更改?
· 是否包括了必要的购买?
· 是否阐明了如何改进重新启用的代码来满足现在的结构设计需求?
· 是否描述并验证了所有主要的数据结构?
· 主要数据结构是否隐含在存取子程序中?
· 规定数据库组织形式和其它内容了吗?
· 是否说明并验证所有关键算法?
· 是否说明验证所有主要目标?
· 说明处理用户输入的策略了吗?
· 说明并验证处理输入/输出的策略了吗?
· 是否定义了用户界面的关键方面?
· 用户界面是否进行了模块化,以使对它所作的改动不会影响程序其它部分?
· 是否描述并验证了内存使用估算和内存管理?
· 是否对每一模块给出了存储空间和速度限制?
· 是否说明了字符串处理策略?是否提供了对字符串占用空间的估计?
· 所提供的错误处理策略是不是一致的?
· 是否对错误信息进行了成套化管理以提供一个整洁的用户界面?
· 是否指定了坚固性级别?
· 有没有哪一部分结构设计被过分定义或缺少定义了?它是否明确说明了?
· 是否明确提出了系统目标?
· 整个结构在概念上是否是一致的?
· 机器和使用实现的语言是否顶层设计依赖?
· 给出做出每个重要决定的动机了吗?
· 你作为系统实现者的程序员,对结构设计满意吗?
3.5 选择编程语言先决条件
程序类型 最好语言 最差语言
结构化数据 Ada、 C++、 Pascal 汇编、Basic
快速而杂乱的项目 Basic Pascal、Ada、 汇编
快速执行 汇编、C 解释性语言如Basic
数学计算 Fortran Pascal
易于维护的程序 Pascal 、Ada C 、Fortran
动态内存使用 Pascal、C Basic
在有限内存环境下运行 Basic、汇编、C Fortran
实时程序 Ada、汇编、C Basic 、Fortran
串操作 Basic 、Pascal C
3.6 编程约定
主要用于提供软件的概念完整性。
3.7 应花在先决条件上的时间
一般用于问题定义,需求分析和总体设计的时间应为20%~30%。
3.8 改变先决条件以适应你的项目
根据项目的大小相应的调整用于先决条件的工作量和时间。
3.9 小结
· 如果想开发一个高质量的软件,必须自始至终重视质量问题。在开始阶段强调质量往往比在最后强调质量更为有效。
· 程序员的份内工作之一便是向老板和同事宣传软件的开发过程,包括在编程开始前从 事先决条件准备工作的重要性。
· 如果问题定义工作做得不好,那么在创建阶段,所解决的问题可能并不是用户真正要 解决的问题。
· 如果需求分析工作做得不好,很可能因此而漏掉要解决问题中的重要细节。在创建工作后更改需求,要比在需求分析阶段进行更改的成本高20 到100 倍。所以,在开始编程前一定要确认需求定义工作一切正常。
· 在编程前规定好约定,在创建工作结束后再改变代码来满足约定几乎是不可能的。
· 在创建活动开始之前如果无法完成准备工作,可以尝试在不太稳固的基础上进行创建活动。