6.1 Metrics and Construction Principles for Maintainability 维修性的度量和构造原则
首先,感谢有道翻译、谷歌翻译、百度翻译对本博文的大力支持。
Outline
- Software Maintenance and Evolution 软件维护和发展
- Metrics of Maintainability 可维护性指标
- Modular Design and Modularity Principles 模块化设计与模块化原理
- OO Design Principles: SOLID OO设计原则:可靠
- OO Design Principles: GRASP OO设计原则:掌握
Software Maintenance and Evolution 软件维护和发展
Software Maintenance(软件维护):软件工程中的软件维护是指在软件产品交付后对其进行修改,以纠正故障,提高性能或其他属性
- 软件维护同软件开发的各阶段均相关
- 确定错误位置
- 测试、修正和文档
- 测试修改是否正确工作
- 检查regression faults(回归性错误)
- 记录所有更改
软件维护的种类:
- 纠正性维护 25%——交付后对软件产品进行反应性修改,以纠正发现的问题
- 适应性维护 21%——交付后对软件产品进行的修改,以保持软件产品在变化或变化的环境中可用
- 完善性维护 50%——交付后增强软件产品的性能或可维护性
- 预防性维护 4%——交付后对软件产品进行修改,以检测和纠正软件产品中的潜在故障,使其成为有效故障。
Software Evolution软件演进/发展
- 软件进化是软件维护中使用的一个术语,指最初开发软件的过程,然后出于各种原因反复更新软件
- 超过90%的典型系统成本发生在维护阶段,任何成功的软件都将不可避免地得到维护
软件需要适应不同的需求和环境
- 制定了八项法律
- 反馈系统Feedback System
- 持续变化Continuing Change
- 持续增长Continuing Growth
- 质量下降Declining Quality
- 复杂性增加Increasing Complexity
- 自我调节Self Regulation
- 保持组织稳定性Conservation of Organizational Stability
- 保持熟悉Conservation of Familiarity
软件维护和发展的目标/责任
- 软件维护和演进的目标:提高软件的适应性和适应性,保持软件的活力,即“持久软件(低熵软件)”
- Linux内核演进的一个例子:可维护性指数
- 维护不仅是维护人员的责任,也是设计和开发者的责任
- 设计和开发者需要考虑软件未来的变化和扩展
面向可维护性的结构示例
- 模块化设计和实现-低耦合和高内聚性
- OO设计原则-扎实-掌握
- OO设计模式-工厂方法模式、构建者模式-桥梁模式、代理模式-记忆模式、状态模式
- 基于状态的构建(基于自动程序设计)
- 表驱动的构建
- GRA基于MMAR的结构
Metrics of Maintainability 可维护性指标
- Maintainability可维护性-“修改软件系统或组件以纠正故障、提高性能或其他属性,或适应变化的环境的容易程度”。容易纠正错误和提高性能
- Extensibility可扩展性-软件设计/实现考虑了未来的发展,并被视为扩展系统能力和实现扩展所需努力水平的系统性度量。易于增加功能
- Flexibility灵活性-软件根据用户需求、外部技术和社会环境等容易改变的能力
- Adaptability适应性-互动系统(适应性系统)的能力,能够根据获得的关于其用户及其环境的信息,使其行为适应个人用户。适用用户个性化需求
- Manageability可管理性:如何有效、轻松地监控和维护软件系统,以保持系统的运行、安全和平稳运行
- Supportability可支持性基于质量文档、诊断信息和知识渊博且可用的技术人员等资源,在部署后如何有效地保持软件的运行。发布后,软件受支持的程度
常用的可维护性指标
- Cyclomatic Complexity循环复杂性
- 衡量代码的结构复杂性
- 独立路径的个数越多则需要更多的测试
- 代码行-表示代码中的大约行数
- 非常高的计数可能表示类型或方法正在尝试做太多的工作,应将其拆分
- 它还可能指示类型或方法可能难以维护。
- halstead volume:基于源代码中(distinct)运算符和操作数的数量的复合度量。运算符和操作数的数目的
- 可维护性索引(MI)-计算介于0和100之间的索引值,该值表示维护代码的相对容易程度。高值意味着更好的可维护性。它的计算基于:
- Halstead volume(hv)
- cyclomatic complexity(cc)
- 每个模块的平均代码行数(loc)
- 每个模块的注释行百分比(com)
- 继承深度-指示扩展到类层次结构根的类定义数。层次结构越深,就越难理解在哪里定义或/和重新定义特定的方法和字段
- 类耦合-通过参数、局部变量、返回类型、方法调用、通用或模板实例化、基类、接口实现、在外部类型上定义的字段和属性修饰来测量与唯一类的耦合
- 良好的软件设计要求类型和方法具有高内聚性和低耦合性
- 高耦合意味着设计很难重用和维护,因为它与其他类型有许多依赖关系
- 单元测试覆盖率-表示自动单元测试覆盖了代码库的哪个部分
Modular Design and Modularity Principles 模块化设计与模块化原理
- 将程序的功能分散到独立可交互的模块中
- 模块化是高层的功能分解技术
- 在结构化编程中是如何根据控制流分解代码
- 在OOP中是指对象中数据的使用方式
Modular programming模块化编程
- 设计的目标是将系统划分为模块,并在组件之间分配责任,方式是:
- 模块内的高内聚性
- 模块之间的松散耦合
- 模块化降低了程序员在任何时候必须处理的总复杂性,假设:
- 功能被分配到模块中,将相似的功能组合在一起(关注点分离)
- 模块之间有小的、简单的、定义明确的接口(信息隐藏)
- 凝聚力和耦合原则可能是评估设计可维护性的最重要设计原则。
Five Criteria for Evaluating Modularity 评价模块性的五个标准
- Decomposability (可分解性) – 较大的组件是否分解成较小的组件?
- Composability (可组合性) – 较大的部件是由较小的部件组成的吗?
- Understandability (可理解性) – Are components separately understandable?
- Continuity (可持续性) – Do small changes to the specification affect a localized and limited number of components? 对规格说明的的改动,其影响是否是局部和有限的
- Protection (保护性) – Are the effects of run-time abnormalities confined to a small number of related components?运行时异常的影响是否仅限于少数相关组件?
- Decomposability (可分解性):将问题分解为各个独立解决的子问题–目标:保持依赖关系显式化和最小化–示例:自上而下的结构设计
- Composability (可组合性): 可容易的将模块 组合起来形成新的系统–目标:使模块可在 不同的环境下复用 – Example: Math libraries; UNIX command & pipes
- Understandability (可理解性): Individual modules understandable by human reader (每个子模块都可被系统设计者容易的理解) – Example: Unix shell such as Program1 | Program2 | Program3 – Counter-example: Sequential Dependencies (A →B → C)
- Continuity (可持续性):规格说 明小的变化将只影响一小部分模块,而不会影响整个体系结构,模块提供的所有服务应该通过统一标识提供
- Protection (保护性):运行时的不正常将局限于小范围模块内
**Five Rules of Modularity Design 模块化设计的五大原则 **
Rule | Meaning | Impact on |
---|---|---|
Direct Mapping直接映射 | 模块的结构与现实世界中问题领域的结构保持一致 | 可持续性 可分解性 |
Few Interfaces 尽可能少的接口 | 模块应尽可能少的与其他模块通讯 | 可持续性、保护性、可理解性、可组合性 |
Small Interfaces 尽可能小的接口 | 如果两个模块通讯,那么它们应交换尽可能 少的信息 | 可持续性 保护性 |
Explicit Interfaces 显式接口 | 当A与B通讯时,应明显的发 生在A与B的接口之间 | 可分解性、可组合性、可持续性、 可理解性 |
Information Hiding 信息隐藏 | 经常可能发生变化的设计决策应 尽可能隐藏在抽象接口后面 | 可持续性 |
Coupling and Cohesion 耦合和内聚
Coupling:
- 耦合是模块之间依赖性的度量。如果一个模块中的更改可能需要另一个模块中的更改,则两个模块之间存在依赖关系
- 模块之间的耦合程度由以下因素决定:–模块之间的接口数量–接口复杂性,通信的复杂性。
Cohesion:
- 内聚是衡量一个模块的功能或职责有多强关联的指标
- 如果一个模块的所有要素都朝着同一个目标努力,那么它具有很高的内聚。
Coupling and Cohesion:
最佳设计在模块内具有高内聚性(也称为强内聚性),在模块之间具有低耦合性(也称为弱耦合)
OO Design Principles: SOLID 实体
- (SRP) The Single Responsibility Principle 单一责任原则
- (OCP) The Open-Closed Principle 开放封闭原则
- (LSP) The Liskov Substitution Principle Liskov 替换原则
- (ISP) The Interface Segregation Principle 接口隔离原则
- (DIP) The Dependency Inversion Principle 依赖转置原则
Open Closed Principle(OCP)开闭原则
- 对扩展是开放的 ,对修改是封闭的,应通过继承和组合改变/扩展功能
- 当软件系统必须支持一组替代方案时,系统中应该有且只有一个 模块知道方案的详尽列表
Liskov substitution principle (LSP) Liskov替代原则
- 关注的是“操作”的可替换性
- 子类型必 须能够替换其基类型
Interface segregation principle (ISP) 接口隔离原则
客户不应该被迫依赖他们 不使用的接口,即保持小接口。
Dependency inversion principle (DIP) 依赖转置原则
- 高层模块不应该依赖于低层 模块,二者都应该依赖于抽象
- 抽象不应该依赖于实现细节,实现细节应该依赖于抽象
Advantages: - 类的契约形式化
- 通过前置和后置条件, 清晰定义子程序的功能
Try Design for Testing: - 形成测试友好的设计
OO设计的两大武器
▪ 抽象(abstraction):模块之间通过抽象隔离开来,将稳定部分和容易 变化部分分开
- LSP:对外界看来,父类和子类是“一样”的;
- DIP:对接口编程,而不是对实现编程,通过抽象接口隔离变化;
- OCP:当需要变化时,通过扩展隐藏在接口之后的子类加以完成,而不要修 改接口本身。
▪ 分离(Separation): Keep It Simple, Stupid (KISS) - SRP:按责任将大类拆分为多个小类,每个类完成单一职责,规避变化,提 高复用度;
- ISP:将接口拆分为多个小接口,规避不必要的耦合。
▪ 归纳起来:让类保持责任单一、接口稳定。
OO Design Principles: GRASP
通用责任分配软件模式 (原则)
GRASP模式是帮助人们理解基本对象设计,并以一种有条理、合理、可解释的方式应用设计推理的学习辅助工具。这种理解和使用设计原则的方法是基于将责任分配给Class的模式
-
对象的责任:对象的义务
-
拥有信息的类负责相应的责任
-
将责任 分配给中间对象,以避免直接耦合
-
Knowing: 掌握
-
Doing: 操作
GRASP是由什么组成的?
▪ ▪ ▪ ▪ ▪ ▪ ▪ ▪
- 控制器 Controller
- 信息专家 Information expert
- 创造者 Creator
- 低耦合 Low coupling
- 高内聚 High cohesion
- 间接的 Indirection
- 多态性 Polymorphism
- 受保护的变体 Protected variations
- 纯虚构 Pure fabrication
Polymorphism多态性
问题:如何根据类型处理备选方案?如何创建可插拔的软件组件?
解决方案:当相关的替代方案或行为因类型(类别)而异时,使用多态操作将行为人的责任分配给行为发生变化的类型。
▪根据多态性原则,将根据类型定义行为变化的责任分配给发生这种变化的类型。
▪这是通过多态操作实现的。
▪类型的用户应该使用多态操作,而不是基于类型的显式分支。
Protected variations 防止变异
Problem: 使对象或系统的内部不稳定性不会对其他元素产生不良影响
Solution:
确定将会发生的变化
分配责任以创建稳定的接口
Pure fabrication 纯虚构
Problem: 无法依靠专家模式实 现高内聚和低耦合时
Solution: 设计虚构的类实现高内聚低耦合和复用