设计模式-六大原则

六大原则

设计模式的六大原则分别是:单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则、迪米特原则和接口隔离原则。

单一职责原则

定义:就一个类而言,应该仅有一个引起它变化的原因。

就是不要让一个类承担过多的职责,否则就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。

开放封闭原则

定义:类、模块、函数等应该是可以拓展的,但是不可修改。

开放封闭有两个含义:一个是对于拓展是开放的,另一个是对于修改是封闭的。

里氏替换原则

定义:所有引用基类(父类)的地方必须能透明地使用其子类的对象。

在软件中将一个基类对象替换成其子类对象,程序将不会产生任何错误和异常;反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。里氏替换原则是实现开发封闭原则的重要方式之一。由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。在使用里氏替换原则时要注意:

  • 子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。根据里氏替换原则,为了保证系统的扩展性,在程序中通常使用父类来进行定义。如果一个方法只存在子类中,在父类中不提供相应的声明。则无法在以父类定义的对象中使用该方法。
  • 在运用里氏替换原则时,尽量把父类设计为抽象类或接口,让子类继承父类或实现父接口,并实现在父类中声明的方法。运行时,子类实例替换父类实例,可以很方便地扩展系统的功能,同时无须修改原有子类的代码;增加新的功能可以通过增加一个新的子类来实现。
  • 在 Java 语言中,在编译阶段,Java 编译器会检查一个程序是否符合里氏替换原则。这是一个与实现无关的、纯语法意义上的检查,但 Java 编译器的检查是有局限性的。

依赖倒置原则

定义:高层模块不应该依赖低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

在 Java 中,抽象指接口或者抽象类,两者都是不能直接被实例化的,细节就是实现类,实现接口或者继承抽象类而产生的就是细节,也就是可以加上一个关键字 new 产生的对象。高层模块就是调用端,低层模块就是具体实现类。依赖倒置原则在 Java 中的表现就是,模块间的依赖通过抽象发生,实现类之间不发生直接依赖关系,其依赖关系是通过接口或者抽象类产生的。如果类与类直接依赖细节,那么就会直接耦合。如此一来当修改时,就会同时修改依赖者代码,这样限制了可扩展性。

迪米特原则

定义:一个软件实体应当尽可能少地与其他实体发生相互作用。

也被称为最少知识原则。使用时要注意:

  • 在类的划分上,应当尽量创建松耦合的类。类之间的耦合度越低,就越有利于复用。一个处在松耦合中的类一旦被修改,则不会对关联的类造成太大波及。
  • 在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限。
  • 在对其他类的引用上,一个对象对其它对象的引用应当降到最低(通过引入一个合理的第三方来降低现有对象之间的耦合度)。

接口隔离原则

定义:一个类对另一个类的依赖应该建立在最小的接口上。

建立单一的接口,不要建立庞大臃肿的接口;尽量细化接口,接口中的方法尽量少。采用接口隔离原则对接口进行约束时要注意:

  • 接口尽量小,但是要有度。对接口进行细化可以提高程序设计的灵活性,但是如果过小,则会造成接口数量过多,使设计复杂化。
  • 为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
  • 提高内聚,减少对外交互。接口方法尽量少用 public 修饰。接口是对外的承诺,承诺越少对系统的开发越有利,变更风险也会越少。

分类

GoF 提出的设计模式总共有 23 种,根据目的准则分类,分为三大类:

  • 创建型设计模式-用于创建对象(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 结构型设计模式-用于组织对象(7 种):适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型设计模式-用于对象之间的通信(11种):策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

备注

参考资料:

Android 进阶之光