HIT软件构造第五章第一节知识点总结


  本章的整体结构与上一章相似,只是内容从可复用性变为了可维护性,也是先进行介绍度量和原则,然后介绍一些设计模式和构造技术。本章内容较多,这篇博客是第一部分,重点是讲解度量和原则。

一.可扩展性的度量与构造原则

  可扩展性,可维护性,灵活性,可适应性,可管理性,支持性等等这些词,含义类似,都是我们这章所讨论的内容。

1.软件的维护和运维

  软件维护主要是修复错误和改善性能,是软件生命周期的最后一部分,一般都在软件发布之后,软件的大部分成本都来自于维护阶段。一个好的软件一般有很好的反馈系统。由于软件总是在不断变化和生长的,因此质量会逐渐降低,复杂性会逐渐增加。
  负责处理这些的是运维工程师,是非常苦的工作。
  进行修改后要进行回归测试(需要足够的文档和测试用例)

2.可维护性的度量

  圈/环复杂度:不同代码独立路径的数量。测试时要将所有独立路径覆盖到。这里有一篇很好的讲解环形复杂度的博客:点此查看
  代码行数:代码行数越多一般说明复杂度越高。但是目前已经是一个非常粗略的判断标准了。
  当然,现在对于可维护性的度量,现在已有可维护性指数了,但是公式复杂,考虑了很多的指标。
  另外还有一些不可量化的指标:例如继承的层次数(越深越不好),类之间的耦合度(越低越好,总之就是一个类的修改最好不会对其他类产生影响),单元测试的覆盖度(覆盖度越高越好)。

3.模块化设计思想和准则

  总的来说,模块化设计的目标是希望模块内高内聚,模块之间高耦合,同时实现分离关注点和信息隐藏。

A.五个评价模块化效果的指标

  我们可以从以下五个方面评价模块化设计是否比较好:
  (1). 可分解性:模块是不是可以分解成多个更小的相互独立的模块,如果可以的话,分解成多个更小的模块更符合模块化设计原则,也就是分而治之的思想。
  (2). 可组合性:可以很容易的将模块之间组合起来形成一整个大的模块(也就是说明了模块之间尽量相互独立)。
  (3). 可理解性:其实就是自己设计出的模块自己非常好理解。
  (4). 可持续性:小的变化只会影响模块的一小部分,不会影响这个系统。例如统一接入模式——模块提供的所有服务应该通过统一标识提供,可以提高可持续性。
  (5). 出现异常之后的保护:运行时出现不正常时尽量把异常局限于小范围内,例如出现问题就抛出异常。

B.模块化设计的五个规则

  我们确定了我们最终要实现的效果之后,接下来我们就要在更底层确定规则,从而实现这些效果。
  (1). 直接映射:模块的结构应该尽量和现实中问题领域的结构保持一致。这有点像之前ADT的设计,其实很多时候尽量保持那种“十分明显的AF”让我们应用起来十分方便。
  (2). 尽可能少的接口:这里的接口不是java中的interface,主要指的是模块与模块之间应该尽量少的通讯。(当然一个系统不可能有孤立的模块,否则就完全没用)
  (3). 尽可能小的接口:同理,就是模块和模块之间应该尽量少的交流;交流太多比如参数什么的过多,一旦修改,就会互相产生很多影响。
  (4). 显式接口:就是两个模块通讯时,就让它发生在这两个模块的接口之间,总之就是不要拐弯抹角,再在其他模块操作。
  (5). 信息隐藏:经常发生变化的部分应该在底层,也就是隐藏在抽象接口的后面(接口在上层)。

C.耦合与内聚

  模块化设计的目标是低耦合高内聚,这两者是相辅相成的,前文也多次提到过,就是模块之间联系少,模块之内内容联系十分紧密,一张形象的符合指标的图如下图所示。
在这里插入图片描述

4.OO设计原则:SOLID

  SOLID为五个原则的首字符缩写,下面我们一一介绍。

A.单一责任原则(SRP)

  内容:ADT中不应该有超过一个原因让其变化,否则就应该拆分开。也就是:一个类,一个责任。
  总的来说,这其实就是让我们把“多功能”的类去拆成“单功能”的类。但一般说来,如果我们的代码比较少,也不需要有频繁的改动,那不必强制遵守这条原则,但这条原则在软件很大且需要频繁的时候,会特别有用,不遵守很有可能是的可扩展性和性能这两方面的大幅度降低。

B.开放/封闭原则(OCP)

  内容:对扩展性开放,即模块的行为是可扩展的;对修改封闭,扩展不应该修改原先已有的代码。
  这也是java中出现的经典的抽象类和接口的使用的“万恶之源”。我们之所以层层抽象,目的就是我们在新增一些类的时候,只需要实现一些接口,本来的调用时调用接口类型,我们在实际传入的参数为这个子类型即可。这种例子数不胜数,是初学java开始就一直被强烈推荐的。

C.Liskov替换原则(LSP)

  已经在前面的博客中详细介绍过了:我是传送门

D.接口隔离原则(ISP)

  内容:不能强迫客户端依赖于它们不需要的接口,只提供必需的接口。
  也就是说,接口要高内聚和精炼,不贪图接口中方法很多。这样类也可以很舒服的按照自己需求实现对应的接口。

E.依赖转置原则(DIP)

  内容:高层模块不应该依赖于低层模块,二者都应该依赖于抽象;抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
  总之就是实现都是依赖于抽象,面向接口编程而不是面向应用编程。这样明显对可复用性和可扩展性都有很大的提升,与OCP相辅相成。

SOLID原则总结

  其实就是如何很好的实现抽象与分离,使得类责任单一,接口稳定。
  抽象:模块之间通过抽象隔离开来,将稳定部分和容易变化部分分开,对应的原则有LSP,DIP,OCP
  分离: Keep It Simple, Stupid,对应的原则有SRP,ISP。

5.OO设计原则:GRASP

  GRASP是关于如何为“类”和“对象”指派“职责”的一系列原则:总的来说是根据类的责任(能得到什么,能做什么等等)来确定职责的搭配。
  一共有9个原则,这里就不细讲了。详细内容可参考《Applying UML and Patterns》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值