软件设计 六大原则

前言:所有的原则缩写都是英文的首字母,如开闭原则(Open Closed Principle)是OCP。

总结场景:

先总结一一各个原则的作用。

  • 开闭原则:六大原则里的一个基础。其他原则都是他的实现或更严格的规范约束。
  • 接口隔离原则:类只服务于一个单一的模块(模块这个概念是一个虚的,需要具体项目具体分析)。
  • 单一职责原则:每个类只有一种作用。
  • 里氏替换原则:父类与子类实现继承关系时,减少(继承的)负面影响。
  • 依赖倒置原则:设计类与类之间的关系时,减少调用方与被调用方实体之间的关联关系。
  • 迪米特原则:从函数的维度,规则调用方与被调用方的职责与联系。

 

开闭原则(Open Closed Principle)

核心

Software entities like classes, modules and functions should be open for extension but closed for modifications.

对扩展开放,对修改关闭。

作用

定义了新增和修改代码时的理想方案。

优缺点

优点:对旧代码无影响,修改或新增功能时,只需要开发和测试的时候新增部分。

缺点:对于只需要改原来代码一两行的情况,需要做重构或新增函数做修改,量比较大。开闭原则使用场景受限,一般只应用于对代码要求很严格的项目。

 

接口隔离原则 (Interface Segregation Principle)

核心

  • 客户端不应该依赖它不需要的接口。
  • 类间的依赖关系应该建立在最小的接口上。

简而言之,理想情况接口只服务于一个模块,不可以被多个模块使用。

作用

给出了接口划分的方法论。

优缺点

优点:

  • 将臃肿庞大的接口分解为多个粒度小的接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。
  • 接口隔离提高了系统的内聚性,减少了对外交互,降低了系统的耦合性。
  • 使用多个专门的接口还能够体现对象的层次,因为可以通过接口的继承,实现对总接口的定义。
  • 能减少项目工程中的代码冗余。过大的大接口里面通常放置许多不用的方法,当实现这个接口的时候,被迫设计冗余的代码。

缺点:不适用于小型项目;接口划分后,数量会增加,提升开发复杂度。

 

单一职责原则(Single Responsibility Principle)

核心

每一个类的职责唯一。

上面那句话看起来就是一句废话,我举例:现在有一个用户类,有属性(姓名,年龄)和动作(上班、回家)。但是类中的方法就包括了【维护属性的函数】(我们叫BO)和【维护动作的函数】(BIZ)。这种情况下用户类的职责就不是唯一的。所以需要拆成两个类。一个只维护用户信息,一个只维护用户动作。

作用

明确一个类所负责的范围,用于定义类。

优缺点

优点:

  • 类的复杂性降低,实现什么职责都有清晰明确的定义;

  • 可读性提高,复杂性减低,可读性当然提高;

  • 可维护性提高,可读性提高,可维护性当然提高;

  • 变更引起的风险减低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的类有影响,对其他接口无影响,这对系统的扩展性、维护性都有非常大的帮助。

缺点:类拆分后类的数量会增加。

单一职责与接口隔离的区别:

  • 根据接口隔离原则拆分接口时,类必须满足单一职责原则。
  • 单一职责原则注重的是职责,而接口隔离原则注重的是对接口依赖的隔离。
  • 单一职责原则主要是约束类,它针对的是程序中的实现和细节;接口隔离原则主要约束接口,主要针对抽象和程序整体框架的构建。

里氏替换原则(Liskov Substitution Principel

核心

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类可以有个性化方法。
  • 当子类的方法重载父类的方法时,子类方法形参比父类形参更宽松,即子类的参数是父类参数的父类型(大于等于的关系)。
  • 当子类的方法实现父类的抽象方法时,子类方法返回是父类方法的子类型(小于等于的关系)。

概括:父类出现的地方子类都可以出现,子类出现的地方父类不一定可以(继承的本质)。

作用

  • 克服了继承中重写父类造成的可复用性变差的缺点。
  • 保证类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。
  • 实现开闭原则的重要方式。

优缺点

继承的优点:

  • 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;
  • 提高代码的重用性;
  • 子类可以形似父类,但又异于父类;
  • 提高代码的可扩展性;
  • 提高产品或项目的开放性。

继承的缺点:

  • 继承是侵入性的,只要继承就必须拥有父类的所有属性和方法;
  • 降低代码的灵活性,子类必须拥有父类的属性和方法,让子类增加了约束;
  • 增强了耦合性,当父类的常量、变量和方法被修改时,必须考虑子类的修改。

 

依赖倒置原则 (Dependence Inversion Principle)

核心

High level modules shouldnot depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details. Details should depend upon abstractions.
  • 高层模块实现不依赖于低层模块。
  • 实现模块依赖于抽象模块,抽象模块不依赖于实现模块。

作用

通过要面向接口的编程来降低类间的耦合性,要求我们在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类。

优缺点

优点:抽象类(对外暴露的类)更通用。

缺点:抽象类与实现类耦合太紧密。

 

迪米特原则(Law of Demeter)(Least Knowledge Principle)

核心

Talk only to your immediate friends and not to strangers.

只关注friend。出现在成员变量、方法的输入输出参数中的类称为friend类,而出现在方法体内部的类不属于friend类。

作用

限制软件实体之间通信的宽度和深度。

如果两个类无须直接通信,那么就不应当发生直接的相互调用,可以通过第三个类转发该调用。(老公,老婆,老婆的公司)

从迪米特法则的定义和特点可知,它强调以下两点:

  1. 从依赖者的角度来说,只依赖应该依赖的对象。
  2. 从被依赖者的角度说,只暴露应该暴露的方法。

优缺点

优点:解耦 ,增加类的可复用率和系统的扩展性。

缺点:过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章