一、单一职责原则(Single Reaponsibility Principle , SRP)
- 就一个类而言,应该仅有一个引起它变化的原因(职责)。
- 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。
- 难点在于如何区分职责、职责的粒度问题。
- 软件设计真正要做的内容,就是发现职责并把那些职责相互分离。
单一职责适用于接口、类,同时也适用于方法。
二、开放封闭原则(Open-Closed Principle , OCP)
-
一个软件应当对扩展开放,对修改关闭。
-
需要考虑:
怎样的设计才能面对需求的改变却可以保持相对稳定,从而使得系统可以在第一个版本以后不断推出新的版本。
-
面对需求,对程序的改动是通过增加新的代码进行的,而不是更改现有代码。
关键:
- 合理地抽象、分离出变化与不变化的部分,为变化的部分预留下可扩展的方式。例如:钩子方法或是动态组合对象等。
- 要完全遵守开闭原则是不可能的,也没这个必要。适当的抽象可以提高系统的灵活性、使其可扩展、可维护;过度抽象,会大大增加系统的复杂程度。
- 钩子方法:是对于抽象方法或者接口中定义的方法的一个空实现。
三、里氏代换原则(Liskov Substitution Principle)
子类型(subtype)必须能够替换它们的基(父)类型。(子类可以以父类的身份出现)
四、依赖倒转原则(Dependence Inversion Principle , DIP)
- 要依赖于抽象,不要依赖于具体。
- 简单的说,依赖倒转原则要求客户端依赖于抽象耦合。原则表述:
- 抽象不应当依赖于具体实现;具体实现应当依赖于抽象;
- 高层模块不应当依赖于底层模块,二者都应该依赖于抽象;
- 要针对接口编程,不针对实现编程。
五、迪米特法则(Law of Demeter , LoD)
又叫最少知识原则(Least Knowledge Principle , LKP)
- 如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
- 也就是说,一个对象应当对其它对象有尽可能少的了解。
- 根本思想是强调类之间的松耦合。
- 类之间的耦合越弱,越有利于复用,一个处于弱耦合的类被修改,不会对有关系的类造成波及。
- 信息的隐藏促进了软件的复用。
六、合成/聚合复用原则
- 要尽量使用合成/聚合,而不是继承关系达到复用的目的。
- 合成/聚合原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。
七、接口隔离原则(ISP)
- 使用多个专门的接口比使用单一的总接口要好。
- 换而言之,从一个客户类的角度讲:一个类对另外一个类的依赖性应当是建立在最小接口上的。
- 过于臃肿的接口是对接口的污染。不应该强迫客户依赖于它们不用的方法。
实现方法:使用多重继承分离接口。