2010-05-28 96 views
5

請考慮以下類比: 如果我們有一個類:「汽車」,我們可能會認爲它有一個「引擎」的實例。如:「汽車HAS-A發動機」。同樣,在「引擎」類中,我們期望有一個「啓動系統」或「冷卻系統」的實例,它們都有相應的子組件。什麼是暴露封裝類方法的經驗法則

由於封裝的性質,汽車「HAS-A」「散熱器軟管」以及發動機是不是真的?

因此,它是適當OO做這樣的事情:

public class Car { 
    private Engine _engine; 

    public Engine getEngine() { 
     return _engine; 
    } 

    // is it ok to use 'convenience' methods of inner classes? 
    // are the following 2 methods "wrong" from an OO point of view? 
    public RadiatorHose getRadiatorHose() { 
     return getCoolingSystem().getRadiatorHose(); 
    } 

    public CoolingSystem getCoolingSystem() { 
     return _engine.getCoolingSystem(); 
    } 
} 

public class Engine { 
    private CoolingSystem _coolingSystem; 

    public CoolingSystem getCoolingSystem() { 
     return _coolingSystem; 
    } 
} 

public class CoolingSystem { 
    private RadiatorHose _radiatorHose; 

    public RadiatorHose getRadiatorHose() { 
     return _radiatorHose; 
    } 
} 

public class RadiatorHose {//... 
} 

回答

2

通過你找麻煩其他封裝類中影響深遠。封裝的關鍵在於你不需要知道該功能是如何實現的,而是需要知道它的功能以及如何訪問它。
如果我想改變冷卻系統和散熱器軟管相互作用的某種方式,發動機應該完全不受影響。在你提出的情況下,這會造成問題。這真的是不正確的面向對象,並將在未來造成問題。

0

作爲一個經驗法則,您可以首先使用自然語言來描述組件之間的關係,這些組件之間最近表現爲類,然後使用某些圖來表示這些關係。如果圖中連接了兩個組件,則它們應該在程序中有特定的連接。在你的情況下,你可以通過觀察圖中這些組件之間是否有連接來確定「引擎」是否是「汽車」的實例,「冷卻系統」是「引擎」的實例。 (這個過程實際上是OO建模語言(如UML)的直覺。)

事實上,我在代碼中看不到任何錯誤。我不是一個汽車人,所以我可能會錯誤地理解這個系統。但是如果真正的汽車發動機需要冷卻系統,我認爲你所做的是正確的。是的,「發動機」類確實稱爲「冷卻系統」類的屬性,但是因爲「引擎」使用公共方法來調用「冷卻系統」,所以這是正確的方式。再次,我不知道真正的汽車系統,所以我可能在這個特定的設計上是錯誤的。

4

這裏是迪米特法則一個真正的好(和很短)的紙稱爲報童,錢包,和法律的迪米特:

http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf

時,您已經閱讀本你應該閱讀這篇短文,其中詳細說明了有多少人曲解了德米特法則。通過這樣做,文章就是一個很好的解釋。它被恰當地稱爲「得墨忒耳的規律不是點數運動」!

http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx

+0

我剛剛完成PDF文件,幾乎已經完成了文章 - 但這可能對別人有幫助。 +1 – javamonkey79 2010-05-29 01:08:46