面向可维护性的构造技术

目前我们写程序很少涉及到维护性,因为我们写的东西不会更新,但在实际应用中,最熟悉的例子就是你玩大型游戏,是不是就会新出一个版本进行更新,或者对游戏中潜在的bug进行修复,这些都是在进行软件维护,当然这都是软件发布后进行的维护,那其实在程序设计的时候就要知道变化是不可避免的,要让自己的程序能够更好的面对变化,容易修改,这就是程序的可维护性。

1.什么是软件维护

软件维护:修复错误,改善性能。

其中大致分为四类:

(1)纠错性 25%

(2)适应性 21%

(3)完善性 50%

(4)预防性 4%

可以看到完善性是软件维护的主要原因,就是完善功能,改善性能,适应变化。这即使重要的原因也是正常的。

2.可维护性指标

这里可维护性也可叫做可扩展性,可适应性等。下面就是衡量可维护性的常用指标

2.1圈/环复杂度

这个指标主要是衡量代码结构的复杂度的,如果有太多的复杂的控制流,就需要及其复杂的测试用例来进行测试代码覆盖,这对于维护来说是很困难的。说白了就是别写太多循环判断语句,更别太多的嵌套。

2.2代码行数

这也好理解,10行能解决的事,非写100行,能不复杂么,维护自然不好维护啊。

而且很多行就很容易导致方法功能的不单一。

2.3可维护性指数

下图为老师提供

2.4继承层数

继承的层数越深,我们之前说过,继承对应的是稳定的复用,也就是说关联性强,那么多层的继承会导致类之间的关联性强,而且很难理解方法或者字段在哪里进行的定义。致使代码的复杂度极高。

2.5类之间的耦合度

好的软件设计应该保证类之间有较低的耦合度,类的内部有较高的聚合性,白说说就是各司其职,那我在代码维护的时候就能根据特定功能的问题进行维护,不至于牵一发而动全身,那可维护性就会很差

2.6单元测试覆盖度

这里很好理解,测试的越全面当然说明可维护性好了

3.模块化设计和模块化原则

这里为什么要插入模块化设计呢,其实我们在之前的学习中我们也能有所涉猎,我们设计一个API就是为了能使用某种特定的功能,我们现在考虑外部指标可维护性时,就要知道,如果我的程序的功能时独立的,那么如果我在使用该功能是发现了错误,那么我很容易就能定位到该程序模块进而专项修改,并且对其他的模块影响很小。所以模块化设计是很重要的,说白了就是各司其职,有责任也好追究。

模块化设计的核心就是:高内聚,低耦合

3.1评价模块化的五种标准

3.1.1可分解性

分解出来的不就是模块么。将问题分解成各个独立解决的子问题,

目标:使得模块之间的依赖关系最小化

3.1.2可组合性

分解的目的是为了使用模块,要很容易的将各个模块进行组合起来组成新的系统

目标:使得模块可在不同环境下复用

3.1.3可理解性

每个模块的功能都能单独容易理解

3.1.4可持续性

一个模块发生变化时对其他模块的影响很小

3.1.5出现异常之后的保护

把异常局限在小范围模块中,便于定位解决

3.2模块化设计的五个规则

3.2.1直接映射

模块的结构与现实世界中问题领域结构保持一致

现实世界的问题大多可以分解,那么模块与现实世界问题的结构一致就保证了分解的要求

因此影响,持续性和可分解性指标

3.2.2尽可能少的于与其他模块通讯

尽量少和其他模块进行通讯,可以理解,如果模块之间的通讯及其复杂,那么可分解性的作用就很小了,而且模块之间的影响也会变大

对可持续性,保护性,可理解性,可组合性指标都有影响

3.2.3减少信息传递

如果必须要通讯,那么就要减少信息交换,也是为了提高独立性

这会对可持续性和保护性产生影响

3.2.4如果要通话要显式

如果要通讯要显式发生在接口之间,就是要让程序员看清楚的看到

影响可分解性,可组合性,可持续性,可理解性

3.2.5信息隐藏

经常发生变化的设计决策应该尽可能的隐藏在抽象接口后面,也就是说让影响最小化

影响可持续性

3.3内聚和耦合

耦合是模块之间依赖程度的度量方法

内聚是衡量模块的功能或者责任强关联的度量方法

高内聚往往与低耦合相关,这也是我们模块化设计的重要要求。说白了就是模块各司其职 ,同时又能协作。

4.OO 设计的SOLID原则

4.1Single Responsibility Principle (SRP) 单一责任原则

ADT中不应该有多于一个原因让其发生变化,否则就拆分开。

交杂不清的职责将使得代码看起来特别别扭,牵一发而动全身。

4.2Open/Closed Principle (OCP) 开放/封闭原则

对扩展性的开放:模块的行为应该是可扩展的,以满足不同变化。

对修改的封闭:模块自身的代码是不应该被修改的,扩展的行为的一般途径是修改模块的内部实现添加代码

关键的决绝方案:抽象技术

将共性通过抽象实现统一,对具体进行针对性的扩展。合理使用子类型多态技术

4.3Liskov Substitution Principle (LSP) 替换原则

这里前一篇文章进行了说明

总的来说就是:进行替换时要满足:更强的不变量,更弱的前置条件,更强的后置条件

4.4Interface Segregation Principle (ISP) 接口隔离原则

要避免大的接口,对客户端来说不应该以来他们不需要的方法,因此接口要尽可能的符合客户端要求的同时尽可能小。

4.5Dependency Inversion Principle (DIP) 依赖转置原则

高层次的模块不应该依赖于低层次模块

具体说就是抽象不应该依赖于实现细节,实现细节应该依赖于抽象

我顶层设计只需要你提供给我ADT,我使用你的ADT接口做我的设计,我不管你是怎么实现的

总结:OO设计的两大武器

抽象模块之间通过抽象隔离开,将稳定的部分和容易变化部分分开

LSP:对外界看来,父类和子类是“一样”的;

DIP :对接口编程,而不是对实现编程,通过抽象接口隔离变化;
OCP :当需要变化时,通过扩展隐藏在接口之后的子类加以完成,而不要修
改接口本身。
分离保证模块的独立与简单
SRP :按责任将大类拆分为多个小类,每个类完成单一职责,规避变化,提
高复用度;
ISP :将接口拆分为多个小接口,规避不必要的耦合。
一句话:让类保持责任单一,接口稳定
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值