2010-01-26 29 views
6
class Room{ 
    public: 
    void ColorRoom(){}; 
}; 

class House{ 
    public: 
    Room* GetRoom(){return &m_room;} 
    private: 
    Room m_room; 
}; 

1)房間不能沒有房子,房子「有一個房間」。 (構圖)
2)另一種彩色房間的方法是在House中有一個方法來調用ColorRoom in Room方法,但這更像是委託。 (我想避免這個)

我看到的唯一方法是上面的一個,但看起來像私人會員的返回引用正在打破面向對象。這是一個很好的設計嗎?純組合是否會破壞OOP概念?

回答

4

總的來說,你很好,因爲House自己創建成員變量m_room - 它不需要消費者在實例化後調用某些東西。這遵循一個項目在實例化後立即可用的模式(它不需要像設置房間或任何其他特殊操作)。

我確實有一些輕微的挑剔採摘:

class Room 
{ 
public: 
    // virtual method to allow overriding 
    virtual void ColorRoom(){}; 
}; 

class House 
{ 
public: 
    // Returning a non-const pointer in C++ is typically a bad smell. 
    const Room& Room() const { return m_room; } 
    // Allow for assignment and manipulating room, but breaks const-ness 
    Room& Room() { return m_room; } 
    // Facade method for houses with more than one room 
    // You can forward parameters or come up with room-painting schemes, but you should 
    // not require that a House has a Room called Room(). 
    virtual void ColorAllRooms() 
    { 
     m_room.ColorRoom(); 
    } 
private: 
    Room m_room; 
}; 
+0

這很好,對於一個簡短的解釋,請參閱我的答案。 – 2010-01-26 18:49:29

+0

請注意,'virtual'是指*覆蓋*而不是*重載*。 – Dario 2010-01-26 18:58:49

+0

你可以重寫一個沒有繼承的函數嗎?其次,如果用戶希望修改房間看起來像他們需要調用房屋的方法,反過來會調用房間的方法,類似於委託。 – 2010-01-26 19:02:17

2

的操作發生在室內,而不是房子。如果你可以通過房子返回一個不變的參考房間,那麼你就不會破壞OOP。

5

問題是你沒有明確暴露你的私人成員。你的API只是展示了一個獲得空間的方法,而且消費者不知道House是否正在創建該房間,返回私人領域中的東西,還是從Web服務中獲取空間。這是堅實的OO。

+2

這非常重要,但請注意,允許外部力量在未經驗證的情況下修改對象狀態通常是不好的設計。 – 2010-01-27 14:53:48

4

我喜歡NickLarsen的答案,但我有一點補充:

不要讓一個對象的私有字段對象以外的區域被改變。如果您必須更改Room對象使用委派。也就是說,如果RoomSetFloorColor(Color _color);方法,那麼你應該投入House調用

SetRoomFloorColor(Color _color){ m_room.SetFloorColor(_color); } 
2

雖然我很喜歡NickLarsen的答案,我想指出一兩件事:房間沒有顏色(或塗料)本身。該行爲通常由Painter完成,顯然,這不是房間的成員。現在一位畫家可以爲整個房子塗上顏色,或者畫家只能在一個房間裏工作。

我會建議在這種情況下,房間有一個顏色屬性,改變顏色的行爲是由另一個對象外部處理。

這個想法暗示着Color屬性必須是一個公共屬性,並且你可以傳遞一個對房間的引用來改變爲Painter對象。

0

揭露私人成員減少凝聚力並增加耦合。一般來說,你應該防止這樣的代碼:

selection.getRecorder().getLocation().getTimeZone(); 

此代碼不易維護,違反Law of Demeter