迪米特法則來自于1987年美國東北大學(Northeastern University)一個名為“Demeter”的研究項目。迪米特法則又稱為最少知識原則(LeastKnowledge Principle, LKP),其定義如下:
迪米特法則(Law of? Demeter, LoD):一個軟件實體應當盡可能少地與其他實體發生相互作用。 |
????? 如果一個系統符合迪米特法則,那么當其中某一個模塊發生修改時,就會盡量少地影響其他模塊,擴展會相對容易,這是對軟件實體之間通信的限制,迪米特法則要求限制軟件實體之間通信的寬度和深度。迪米特法則可降低系統的耦合度,使類與類之間保持松散的耦合關系。
????? 迪米特法則還有幾種定義形式,包括:不要和“陌生人”說話、只與你的直接朋友通信等,在迪米特法則中,對于一個對象,其朋友包括以下幾類:
??? ? (1) 當前對象本身(this);
???? ?(2) 以參數形式傳入到當前對象方法中的對象;
????? (3) 當前對象的成員對象;
????? (4) 如果當前對象的成員對象是一個集合,那么集合中的元素也都是朋友;
????? (5) 當前對象所創建的對象。
????? 任何一個對象,如果滿足上面的條件之一,就是當前對象的“朋友”,否則就是“陌生人”。在應用迪米特法則時,一個對象只能與直接朋友發生交互,不要與“陌生人”發生直接交互,這樣做可以降低系統的耦合度,一個對象的改變不會給太多其他對象帶來影響。
????? 迪米特法則要求我們在設計系統時,應該盡量減少對象之間的交互,如果兩個對象之間不必彼此直接通信,那么這兩個對象就不應當發生任何直接的相互作用,如果其中的一個對象需要調用另一個對象的某一個方法的話,可以通過第三者轉發這個調用。簡言之,就是通過引入一個合理的第三者來降低現有對象之間的耦合度。
????? 在將迪米特法則運用到系統設計中時,要注意下面的幾點:在類的劃分上,應當盡量創建松耦合的類,類之間的耦合度越低,就越有利于復用,一個處在松耦合中的類一旦被修改,不會對關聯的類造成太大波及;在類的結構設計上,每一個類都應當盡量降低其成員變量和成員函數的訪問權限;在類的設計上,只要有可能,一個類型應當設計成不變類;在對其他類的引用上,一個對象對其他對象的引用應當降到最低。
????? 下面通過一個簡單實例來加深對迪米特法則的理解:
????? Sunny軟件公司所開發CRM系統包含很多業務操作窗口,在這些窗口中,某些界面控件之間存在復雜的交互關系,一個控件事件的觸發將導致多個其他界面控件產生響應,例如,當一個按鈕(Button)被單擊時,對應的列表框(List)、組合框(ComboBox)、文本框(TextBox)、文本標簽(Label)等都將發生改變,在初始設計方案中,界面控件之間的交互關系可簡化為如圖1所示結構: 圖1?初始設計方案結構圖 ????? 在圖1中,由于界面控件之間的交互關系復雜,導致在該窗口中增加新的界面控件時需要修改與之交互的其他控件的源代碼,系統擴展性較差,也不便于增加和刪除新控件。 ????? 現使用迪米特對其進行重構。 |
????? 在本實例中,可以通過引入一個專門用于控制界面控件交互的中間類(Mediator)來降低界面控件之間的耦合度。引入中間類之后,界面控件之間不再發生直接引用,而是將請求先轉發給中間類,再由中間類來完成對其他控件的調用。當需要增加或刪除新的控件時,只需修改中間類即可,無須修改新增控件或已有控件的源代碼,重構后結構如圖2所示:
圖2 ?重構后的結構圖