2014-02-06 18 views
0

只是想改善我在Python中的OO使用,並且很好奇組合。Python組合

比方說你有以下類:

Class Breakfast(object): 
    __init__(self, eggs): 
     self.eggs = eggs 

    @property 
    def yolk(self): 
     return eggs.yolk 

    @property 
    def yolk_colour(self): 
     return eggs.yolk.colour 
     OR 
     return.eggs.yolk_colour 

Class Eggs(object): 
    __init__(self, yolk): 
     self.yolk = yolk 

    @property 
    def yolk_colour(self): 
     return self.yolk.colour 

Class Yolk(object): 
    __init__(self, colour): 
     self.colour = colour 

並初始化它們

eggs = Eggs(Yolk("yellow")) 
bkfast = Breakfast(eggs) 

當你要訪問的蛋黃,是它更好地鏈它作爲

bkfast.eggs.yolk 

或通過屬性訪問它

bkfast.yolk 

第二個版本直接使用較少的鏈接,雖然仍然在幕後。而第一個告訴你到底發生了什麼。有沒有一個首選的方法呢?

編輯:我已經把蛋黃屬性,它有一種顏色。如果你想從早餐中得到那種顏色,最好有一個叫做雞蛋屬性的早餐,或者直接進入蛋黃本身?或者它在幕後是不是很重要?

+3

http://en.wikipedia.org/wiki/Law_of_Demeter - 使用後一選項 –

+0

http://www.python.org/dev/peps/pep-0020/ Python的禪:Explicit比隱含更好。簡單勝於複雜。 – Cilyan

+0

我認爲你應該使用getter方法。 – 2rs2ts

回答

3

在某些方面人爲設計的類泥濘的問題。它在某種程度上取決於您要做什麼,或者具體定義您正在使用的對象圖的方式。從breakfast跳到yolk是不自然的......你不可能直接跳到早餐總數的蛋黃孩子。

在這種情況下,合同可能是早餐會提供egg對象,所以這是你將返回,然後從那裏得到蛋黃,如果需要的話(但那隻涉及egg對象... breakfast停止關心

如果出於某種原因,您確實想要持續抓取蛋黃,那麼您應該使用授權。您永遠不希望您的客戶代碼關心的事情超過它必須或應該(Demeter Law of above) ,並且除了定義和管理的API泄露給客戶端代碼之外,您從不想擁有任何其他內容。

更合理的示例假設你有不同形式的雞蛋和早餐,所以它可能來自一個盤子,或一個水煮雞蛋架,或來自玻璃,「洛基」風格。在這種情況下,客戶端代碼仍然只是想要雞蛋,所以你想使用代表團並將蛋取出適當的盤子,立場或玻璃小孩。

歸結到一點,定義它是什麼,你都暴露在客戶端代碼,並確保任何行李或實施細節的處理和由接收對象進行抽象。你總是想根據你所提供的而不是來自哪裏。

+0

感謝您的回覆。代替誠然做作早餐例子的話,我有一個類容器,其充當一個樹形數據結構的容器(其具有它自己的類樹)。那棵樹有一個root_node。我想從客戶端代碼隱藏Tree的工作,因此Container有實用的方法來訪問它。這對我來說很有意義。 –

+0

Container是如何訪問根節點的?即說根節點本身有一個屬性「值」,客戶端需要知道這一點。容器有一個屬性'root_value'來提供這個功能。如果這個root_value屬性調用類似'self.tree.root_node.value'的東西,或者調用一個也是root_value的樹屬性,從而返回'self.tree.root_value',這有什麼關係嗎? –

+0

這又取決於你在設計什麼。最短的答案是不要過度工程,所以如果你不暴露目前的實例外的對象,那麼你不必擔心它。如果你不必擔心它......如果'tree'暴露在其他地方,並且你正在從實現到API旅行,那麼上面的相同原則應該適用於它。如果是這樣的話,我會說你確實需要在那裏使用明智的授權,因爲從樣本調用來看,客戶端代碼甚至不應該在意它是一棵樹。 –

2

在我看來,對於這個特定的例子,最好通過屬性bkfast.yolk來訪問它,因爲那樣你就有了改變蛋黃底層實現的自由。

0

The Zen of Python

Explicit is better than implicit. 
Simple is better than complex. 

對我來說,這意味着你的例子並沒有什麼意義沒有一個具體的問題。如果您需要撰寫,請撰寫。如果你不需要,不要。想想你的界面的含義,保持它簡單顯式

不管怎樣,早餐的蛋黃是什麼?