天天看點

設計原則_LOD原則

文章目錄

  • ​​1.迪米特法則​​
  • ​​2.高内聚​​
  • ​​3.松耦合​​
  • ​​4.代碼​​
  • ​​5.總結​​

1.迪米特法則

  1. 迪米特法則的英文翻譯是:Law of Demeter,縮寫是 LOD。
  2. 單從這個名字上來看,我們完全猜不出這個原則講的是什麼。不過,它還有另外一個更加達意的名字,叫作最小知識原則,英文翻譯為:The Least Knowledge Principle。
  3. 它不像 SOLID、KISS、DRY 原則那樣,人盡皆知,但它卻非常實用。利用這個原則,能夠幫我們實作代碼的“高内聚、松耦合”
  4. “高内聚、松耦合”是一個非常重要的設計思想,能夠有效地提高代碼的可讀性和可維護性,縮小功能改動導緻的代碼改動範圍
  5. 很多設計原則都以實作代碼的“高内聚、松耦合”為目的,比如單一職責原則、基于接口而非實作程式設計等
  6. “高内聚、松耦合”是一個比較通用的設計思想,可以用來指導不同粒度代碼的設計與開發,比如系統、子產品、類,甚至是函數,也可以應用到不同的開發場景中,比如微服務、架構、元件、類庫等
  7. ​不該有直接依賴關系的類之間,不要有依賴;有依賴關系的類之間,盡量隻依賴必要的接口​

    ​(也就是定義中的“有限知識”)
設計原則_LOD原則

2.高内聚

就是指相近的功能應該放到同一個類中,不相近的功能不要放到同一個類中。相近的功能往往會被同時修改,放到同一個類中,修改會比較集中,代碼容易維護

3.松耦合

4.代碼

public class Serialization {
  public String serialize(Object object) {
    String serializedResult = ...;
    //...
    return serializedResult;
  }
  
  public Object deserialize(String str) {
    Object deserializedResult = ...;
    //...
    return deserializedResult;
  }
}      
  1. 假設在我們的項目中,有些類隻用到了序列化操作,而另一些類隻用到反序列化操作。
  2. 那基于迪米特法則後半部分“有依賴關系的類之間,盡量隻依賴必要的接口”,隻用到序列化操作的那部分類不應該依賴反序列化接口。同理,隻用到反序列化操作的那部分類不應該依賴序列化接口。
public class Serializer {
  public String serialize(Object object) {
    String serializedResult = ...;
    ...
    return serializedResult;
  }
}

public class Deserializer {
  public Object deserialize(String str) {
    Object deserializedResult = ...;
    ...
    return deserializedResult;
  }
}      
  1. 将 Serialization 類拆分為兩個更小粒度的類,一個隻負責序列化(Serializer 類),一個隻負責反序列化(Deserializer 類)。拆分之後,使用序列化操作的類隻需要依賴 Serializer 類,使用反序列化操作的類隻需要依賴 Deserializer 類
  2. 管拆分之後的代碼更能滿足迪米特法則,但卻違背了高内聚的設計思想。高内聚要求相近的功能要放到同一個類中,這樣可以友善功能修改的時候,修改的地方不至于過于分散。對于剛剛這個例子來說,如果我們修改了序列化的實作方式,比如從 JSON 換成了 XML,那反序列化的實作邏輯也需要一并修改。在未拆分的情況下,我們隻需要修改一個類即可
public interface Serializable {
  String serialize(Object object);
}

public interface Deserializable {
  Object deserialize(String text);
}

public class Serialization implements Serializable, Deserializable {
  @Override
  public String serialize(Object object) {
    String serializedResult = ...;
    ...
    return serializedResult;
  }
  
  @Override
  public Object deserialize(String str) {
    Object deserializedResult = ...;
    ...
    return deserializedResult;
  }
}

public class DemoClass_1 {
  private Serializable serializer;
  
  public Demo(Serializable serializer) {
    this.serializer = serializer;
  }
  //...
}

public class DemoClass_2 {
  private Deserializable deserializer;
  
  public Demo(Deserializable deserializer) {
    this.deserializer = deserializer;
  }
  //...
}      
  1. 盡管我們還是要往 DemoClass_1 的構造函數中,傳入包含序列化和反序列化的 Serialization 實作類,但是,我們依賴的 Serializable 接口隻包含序列化操作,DemoClass_1 無法使用 Serialization 類中的反序列化接口,對反序列化操作無感覺,
  2. 這也就符合了迪米特法則後半部分所說的“依賴有限接口”的要求。

5.總結

  1. 展現了“基于接口而非實作程式設計”的設計原則,結合迪米特法則,我們可以總結出一條新的設計原則,那就是“基于最小接口而非最大實作程式設計”
  2. 目的都是實作高内聚低耦合,但是出發的角度不一樣,單一職責是從自身提供的功能出發,迪米特法則是從關系出發,針對接口而非實作程式設計是使用者的角度,殊途同歸

繼續閱讀