设计模式的基本原则
- 单一职责原则 (Single Responsibility Principle)
- 开放-关闭原则 (Open-Closed Principle)
- 里氏替换原则 (Liskov Substitution Principle)
- 依赖倒转原则 (Dependence Inversion Principle)
- 接口隔离原则 (Interface Segregation Principle)
- 迪米特法则(Law Of Demeter)
- 组合/聚合复用原则 (Composite/Aggregate Reuse Principle)
1.单一职责原则 SRP(Single Responsibility Principle)
就一个类而言,应该仅有一个让它变化的原因;通俗地说,即一个类只负责一项职责。
- SRP 是一个简单又直观的原则,但是在实际编码的过程中很难将它恰当地运用,需要结合实际情况进行运用。
- 单一职责原则可以降低类的复杂度,一个类仅负责一项职责,其逻辑肯定要比负责多项职责简单。
- 提高了代码的可读性,提高系统的可维护性。
2. 开放-关闭原则 OCP (Open-Closed Principle)
软件实体 (类、模块、函数等等) 对扩展开放,对修改关闭
如果一个软件能够满足 OCP 原则,那么它将有两项优点:
- 能够扩展已存在的系统,能够提供新的功能满足新的需求,因此该软件有着很强的适应性和灵活性。
- 已存在的模块,特别是那些重要的抽象模块,不需要被修改,那么该软件就有很强的稳定性和持久性。
3. 里氏替换原则 LSP(Liskov Substitution Principle)
里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能(如果改变了,父类可能就没有存在的必要了)。
里氏替换原则的重点在不影响原功能,而不是不覆盖原方法。
4. 依赖倒转原则 DIP (Dependence Inversion Principle)
高层模块不应该依赖低层模块,二者都应该依赖于抽象。进一步说,抽象不应该依赖于细节,细节应该依赖于抽象。
依赖倒转原则的核心思想就是面向接口编程
5. 接口隔离原则 ISP (Interface Segregation Principle)
接口隔离原则强调:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

这个图的意思是:类A依赖接口I中的方法1、方法2、方法3,类B是对类A依赖的实现。类C依赖接口I中的方法1、方法4、方法5,类D是对类C依赖的实现。对于类B和类D来说,虽然他们都存在着用不到的方法(也就是图中红色字体标记的方法),但由于实现了接口I,所以也必须要实现这些用不到的方法。
用代码表示:
interface I {
public void method1();
public void method2();
public void method3();
public void method4();
public void method5();
}
class A{
public void depend1(I i){
i.method1();
}
public void depend2(I i){
i.method2();
}
public void depend3(I i){
i.method3();
}
}
class B implements I{
// 类 B 只需要实现方法 1,2, 3,而其它方法它并不需要,但是也需要实现
public void method1() {
System.out.println("类 B 实现接口 I 的方法 1");
}
public void method2() {
System.out.println("类 B 实现接口 I 的方法 2");
}
public void method3() {
System.out.println("类 B 实现接口 I 的方法 3");
}
public void method4() {}
public void method5() {}
}
class C{
public void depend1(I i){
i.method1();
}
public void depend2(I i){
i.method4();
}
public void depend3(I i){
i.method5();
}
}
class D implements I{
// 类 D 只需要实现方法 1,4,5,而其它方法它并不需要,但是也需要实现
public void method1() {
System.out.println("类 D 实现接口 I 的方法 1");
}
public void method2() {}
public void method3() {}
public void method4() {
System.out.println("类 D 实现接口 I 的方法 4");
}
public void method5() {
System.out.println("类 D 实现接口 I 的方法 5");
}
}
public class Client{
public static void main(String[] args){
A a = new A();
a.depend1(new B());
a.depend2(new B());
a.depend3(new B());
C c = new C();
c.depend1(new D());
c.depend2(new D());
c.depend3(new D());
}
}
可以看出,如果接口定义的过于臃肿,只要接口中出现的方法,不管依赖于它的类是否需要该方法,实现类都必须去实现这些方法,这就不符合接口隔离原则,如果想符合接口隔离原则,就必须对接口 I 如下图进行拆分:

代码可修改为如下:
interface I1 {
public void method1();
}
interface I2 {
public void method2();
public void method3();
}
interface I3 {
public void method4();
public void method5();
}
class A{
public void depend1(I1 i){
i.method1();
}
public void depend2(I2 i){
i.method2();
}
public void depend3(I2 i){
i.method3();
}
}
class B implements I1, I2{
public void method1() {
System.out.println("类 B 实现接口 I1 的方法 1");
}
public void method2() {
System.out.println("类 B 实现接口 I2 的方法 2");
}
public void method3() {
System.out.println("类 B 实现接口 I2 的方法 3");
}
}
class C{
public void depend1(I1 i){
i.method1();
}
public void depend2(I3 i){
i.method4();
}
public void depend3(I3 i){
i.method5();
}
}
class D implements I1, I3{
public void method1() {
System.out.println("类 D 实现接口 I1 的方法 1");
}
public void method4() {
System.out.println("类 D 实现接口 I3 的方法 4");
}
public void method5() {
System.out.println("类 D 实现接口 I3 的方法 5");
}
}
- 接口隔离原则的思想在于建立单一接口,尽可能地去细化接口,接口中的方法尽可能少
- 但是凡事都要有个度,如果接口设计过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
6. 迪米特法则 LOD(Law Of Demeter),又称最少知道原则
它表示一个对象应该对其它对象保持最少的了解。通俗来说就是,只与直接的朋友通信。
首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。
对于被依赖的类来说,无论逻辑多么复杂,都尽量的将逻辑封装在类的内部,对外提供 public 方法,不对泄漏任何信息。
7. 组合/聚合复用原则 CRP(Composite/Aggregate Reuse Principle)
组合/聚合复用原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分; 新的对象通过向这些对象的委派达到复用已有功能的目的。
在面向对象的设计中,如果直接继承基类,会破坏封装,因为继承将基类的实现细节暴露给子类;如果基类的实现发生了改变,则子类的实现也不得不改变;从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性。于是就提出了组合/聚合复用原则,也就是在实际开发设计中,尽量使用组合/聚合,不要使用类继承。
- 总体说来,组合/聚合复用原则告诉我们:组合或者聚合好过于继承。
- 聚合组合是一种 “黑箱” 复用,因为细节对象的内容对客户端来说是不可见的。
浙公网安备 33010602011771号