2011年3月31日 星期四

[OO 設計原則] Low of Demeter


前言 :
Law of Demeter (LoD),最少知識原則 : 一個物件盡可能的少知道其他物件,反之,物件本身提供最少訊息給其他物件。那麼"知識"一詞又是代表何種意義??就是,一個物件本身提供最少的 public variable 及 public method 給外界使用.

狹義的LoD :
如果兩個 class 不必彼此直接溝通,那麼這兩個 class 就不應該直接互相發生作用,如果其中一個 class 有必須要與之溝通,則可以透過第三者來 Call Forwarding.

若滿足 :
- 物件本身(this)
- 以參數形式傳送給該物件method 的物件
- 此物件 variable 中直接 reference 的物件,i.e. 此物件內的物件 variable
- 此物件為聚集物件,則聚集中的所有物件抑是
- 此物件所建構的物件

其中之一,則為可以直接溝通的 class ,否則就必須透過第三者來轉發. 由於轉發其他物件的訊息給另一個物件,所以系統中會存在許許多多的小method 作為轉發訊息之用,這也使得設計師在觀察系統的 UML 圖時,會造成困惑,也因為訊息必須透過轉發而不是直接溝通,所以身在兩個遙遠的物件,必須透過多層次的溝通,也就產生了物件之間的不容易協調. 所以 Kirk Knoernschild 在 JAVA Design 一書中提到,為了克服這種狹義的 LoD ,我們可以配合 DIP (Dependency Inversion Principle) 來加入抽象 class,使得兩個不能溝通的物件彼此依賴於此 abstract class.

廣義的LoD :
廣義的 LoD 就是對物件之間的通訊傳輸量的控制,目的為了控制資訊的超載. 在軟體設計中,一個 class 設計的好壞,取決於將自己內部資訊及時做隱藏的程度,透過 information hiding及 encapsulation 來達成. 而運用 LoD 於系統上時必須注意 :
1. 設計系統中的 class 時,應當建構出耦合度越低越好 :
若是兩個 class 耦合度越高,當系統面臨修改或是維護時,此兩個 class 會產生瓶頸,造成修改上的困難,因為可能在這裡動一刀,另一個 class 就完全不能運作了!我們可以透過降低耦合度來提高 class 的 reusability.

2. 在 class 設計上,應當降低 field 的 Accessibility :
透過 modification 來提供存取的限制。一個 class 被製造發佈後,提供者就無法將原 先的 public variable or public method 更改為 private,因為可能已經有部分用戶這在使用,若更改,則產生所有 client 的影響,所以設計 class 應當降低對外開放的資訊,並審慎的提供外部資訊.

3. 設 class 設計上,只要有可能,就應當將此 class 設計為 immutable class :
immutable class 之五大原則 :
A. 不提供任何可修改物件內容的 method
B. 保證沒有 method 可以被 override。i.e. 使 class 為 final or 使所有 method 為 final or 使 constructor 為 private,並且提供一個 public static factory method
C. 令所有 field 為 final 並不使用同步機制
D. 令所有的 field 為 private
E. 確保對所有的 mutable components 提供 exclusive access

4. 對其他 class 的 reference 上,一個物件對其物件的 reference 應該降到最低 :
當所 reference 的物件提供相當多的資訊時,我們就必須降低對其資訊的依賴,達成此項目的.

補充說明 :
Dependency Inversion Principle :
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...