开闭原则

遵循开闭原则设计出的模块具有两个主要特征:

  • 对于扩展是开放的(Open for extension)
  • 对于修改是关闭的(Closed for modification)

满足开闭原则的设计可以给软件系统带来两个好处:

  • 通过扩展可以提供新的功能,使软件有一定的适应性和灵活性
  • 已有的模块,特别是抽象层模块部能再修改,使软件有一定的稳定性

如果要实现开闭原则,抽象化是关键。例如,可以设计一个或多个抽象 JAVA 类或者接口,这个抽象层预见了所有的可能扩展。这样就使得抽象层不需要修改,如果需要新增功能,可以实现这些抽象类或者接口。

里氏替换原则(LSP)

里氏替换原则是指:

如果对每一个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都替换成 o2时,程序 P 的行为没有变化,那么类型 T2 是类型 T1 的子类型。

里氏替换原则是继承复用的基石。只有当子类可以替换掉基类,软件功能不受到影响时,基类才能被真正复用,而子类也可以在基类的基础上增加新的功能。

但是上面的替换反过来则不成立,就是不可以用父类对象替代子类对象。

依赖倒转原则(DIP)

依赖倒转原则主要是:要依赖抽象,不要依赖具体。

在面向对象的系统当中,两个类之间可能发生三种不同的耦合关系:

  • 零耦合
  • 具体耦合:指发生在两个具体的类之间,一个类对另外一个类直接引用造成
  • 抽象耦合:指一个具体类与一个抽象类之间,使两个必须发生关系的类之间存在最大的灵活性

依赖倒转原则要求客户端依赖于抽象耦合,抽象不要依赖与细节,细节要依赖于抽象。也可以说成是,依赖于接口编程。

接口隔离原则(ISP)

使用多个专门的接口比使用单一的总接口要好。

一个类对另外一个类的依赖性应当是建立在最小的接口上的。

一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。

“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。

合成、聚合复用原则(CARP)

要尽量使用合成、聚合,尽量不使用继承。

在面向对象的设计里,复用一般有两种方式:

  • 继承
  • 合成或聚合

迪米特法则(LoD)

迪米特法则又叫最少知识原则,就是说,一个对象应当对其他对象有尽可能少的了解。

迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。

迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。

—EOF—