设计原则 - 迪米特原则

迪米特原则(最少知道原则):无需直接交互的两个类,如果需要交互,使用中间者

含义

  • 迪米特原则(Law of Demeter,LoD)是指一个对象应该对其他对象保持最少的了解,又叫最少知道原则(Least Knowledge Principle,LKP)尽量降低类与类之间的耦合。
  • 一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的 public 方法,不对外泄漏任何信息。迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现当前对象本身、当前对象的成员变量、当前对象创建的对象、如果当前对象的成员变量是一个集合,集合中的元素、方法参数、方法返回值中的类直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。
  • 一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。也就是说一个软件实体应当尽可能少的与其他实体发生相互作用。这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,它要求限制软件实体之间通信的宽度和深度。

核心思想

  • 一个对象应该对其他对象保持最少的了解
  • 降低类之间的耦合度,类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大,比如说当一个类方法里面依赖了另一个类,当这个依赖的类方法发生改变时,被依赖的类方法里面就得重新修改为该依赖类的新方法,违背了设计原则的开闭原则。

优点

  • 降低了类之间的耦合度,提高了模块的相对独立性
  • 由于亲合度降低,从而提高了类的可复用率和系统的扩展性

案例

现在需要实现人进行洗衣服的功能。实现该功能我们需要两个类:一个表示人的类,具有洗衣服的方法。一个表示洗衣机的类,具有接收衣服、洗涤和烘干三个方法。

public class WashingMachine {
    
    

  // 接收衣服的方法
  public void receiveClothes() {
    
    
    System.out.println("菜鸟牌洗衣机,开始接收衣服了!");
  }

  // 洗涤的方法
  public void wash() {
    
    
    System.out.println("菜鸟牌洗衣机,开始洗衣服了!");
  }

  // 烘干的方法
  public void drying() {
    
    
    System.out.println("菜鸟牌洗衣机,开始烘干衣服了!");
  }
}

public class Person {
    
    

  // 使用洗衣机洗衣服的方法
  public void washClothes(WashingMachine washingMachine) {
    
    
    System.out.println("小菜鸟拿好衣服准备清洗。");
    washingMachine.receiveClothes();
    washingMachine.wash();
    washingMachine.drying();
  }

}

通过以上两个类就可以实现洗衣服的功能,但是这种实现是不符合最少知道原则

其实很简单,相对于 Person 类来说,我们是要实现洗衣服的功能,具体洗衣机如何洗?我们是不需要了解的。但是上面 Person 类中的 washClothes 方法,却一连调用了 WashingMachine 类的三个方法。并且这三个方法都是洗衣机需要做的,跟我们人没有什么关系。这就造成了 Person 类对 WashingMachine 类知道的太多了。

解决该问题的方法也很简单,其根源是在本类自己,从根源上约束自己,尽量不暴露一些独属于自己的方法和属性。可以简单理解为,每个类都是要有属于自己的秘密。这样就可以使其它类对自己知道的更少。

案例改进

public class WashingMachine {
    
    

  // 自动洗衣
  public void automatic() {
    
    
    this.receiveClothes();
    this.wash();
    this.drying();
  }

  // 接收衣服的方法
  private void receiveClothes() {
    
    
    System.out.println("菜鸟牌洗衣机,开始接收衣服了!");
  }

  // 洗涤的方法
  private void wash() {
    
    
    System.out.println("菜鸟牌洗衣机,开始洗衣服了!");
  }

  // 烘干的方法
  private void drying() {
    
    
    System.out.println("菜鸟牌洗衣机,开始烘干衣服了!");
  }
}

public class Person {
    
    

  // 使用洗衣机洗衣服的方法
  public void washClothes(WashingMachine washingMachine) {
    
    
    System.out.println("小菜鸟拿好衣服准备清洗。");
    washingMachine.automatic();
  }

}

过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。

猜你喜欢

转载自blog.csdn.net/qq_42700109/article/details/132860942