可维护性的度量与构造原则
软件的维护和演化
- 定义:软件可维护性是指软件产品被修改的能力,修改包括纠正、改进或软件对环境、需求和功能规格说明变化的适应。简而言之,软件维护:修复错误、改善性能。
- 类型:纠错性(25%)、适应性(25%)、完善性(50%)、预防性(4%)
- 演化:软件演化是一个程序不断调节以满足新的软件需求过程。
- 演化的规律:软件质量下降,延续软件生命
- 软件维护和演化的目标:提高软件的适应性,延续软件生命 。
- 意义:软件维护不仅仅是运维工程师的工作,而是从设计和开发阶段就开始了 。在设计与开发阶段就要考虑将来的可维护性 ,设计方案需要“easy to change”
- 基于可维护性建设的例子:
- 模块化
- OO设计原则
- OO设计模式
- 基于状态的构造技术
- 表驱动的构造技术
- 基于语法的构造技术
可维护性的常见度量指标
- 软件可维护性的五个子特性:
- 易分析性。软件产品诊断软件中的缺陷或失效原因或识别待修改部分的能力。
- 易改变性。软件产品使指定的修改可以被实现的能力,实现包括编码、设计和文档的更改。如果软件由最终用户修改,那么易改变性可能会影响易操作性。
- 稳定性。软件产品避免由于软件修改而造成意外结果的能力。
- 易测试性。软件产品使已修改软件能被确认的能力。
- 维护性的依从性。软件产品遵循与维护性相关的标准或约定的能力。
- 一些常用的可维护性度量标准:
- 圈复杂度(CyclomaticComplexity):度量代码的结构复杂度。
- 代码行数(Lines of Code):指示代码中的大致行数。
- Halstead Volume:基于源代码中(不同)运算符和操作数的数量的合成度量。
- 可维护性指数(MI):计算介于0和100之间的索引值,表示维护代码的相对容易性。 高价值意味着更好的可维护性。
继承的层次数:表示扩展到类层次结构的根的类定义的数量。 等级越深,就越难理解特定方法和字段在何处被定义或重新定义。 - 类之间的耦合度:通过参数,局部变量,返回类型,方法调用,泛型或模板实例化,基类,接口实现,在外部类型上定义的字段和属性修饰来测量耦合到唯一类。
- 单元测试覆盖率:指示代码库的哪些部分被自动化单元测试覆盖。
模块化设计规范:聚合度与耦合度
- 模块化编程的含义:模块化编程是一种设计技术,它强调将程序的功能分解为独立的可互换模块,以便每个模块都包含执行所需功能的一个方面。
- 设计规范:高内聚低耦合
- 评估模块化的五个标准:
- 可分解性:将问题分解为各个可独立解决的子问题
- 可组合性:可容易的将模块组合起来形成新的系统
- 可理解性:每个子模块都可被系统设计者容易的理解
- 可持续性:小的变化将只影响一小部分模块,而不会影响整个体系结构
- 出现异常之后的保护:运行时的不正常将局限于小范围模块内
- 模块化设计的五条原则:
- 直接映射:模块的结构与现实世界中问题领域的结构保持一致
- 尽可能少的接口:模块应尽可能少的与其他模块通讯
- 尽可能小的接口:如果两个模块通讯,那么它们应交换尽可能少的信息
- 显式接口:当A与B通讯时,应明显的发生在A与B的接口之间
- 信息隐藏:经常可能发生变化的设计决策应尽可能隐藏在抽象接口后面
内聚性
- 又称块内联系。指模块的功能强度的度量,即一个模块内部各个元素彼此结合的紧密程度的度量。若一个模块内各元素(语名之间、程序段之间)联系的越紧密,则它的内聚性就越高。
- 所谓高内聚是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。
耦合性
- 也称块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息。
- 对于低耦合,粗浅的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。这样有利于修改和组合。