纯粹的构图是否破坏了OOP概念?

时间:2010-01-26 18:37:34

标签: oop composition

class Room{
  public:
    void ColorRoom(){};
};

class House{
  public:
    Room* GetRoom(){return &m_room;}
  private:
    Room m_room;
};
1)房间不能没有房子,房子“有”房间。 (组合物)
2)色彩空间的另一种方法是在House中使用一种方法来调用Room方法中的ColorRoom,但这更像是委托。 (我想避免这种情况)

我看到的唯一方法是上面的那个,但看起来像私有成员的返回引用正在破坏OOP。这是一个很好的设计吗?

6 个答案:

答案 0 :(得分:5)

问题是你没有明确地暴露你的私人成员。您的API只显示获取房间的方法,而消费者不知道House是否正在创建该房间,返回私人字段中保存的内容,或者从Web服务获取房间。那是坚实的OO。

答案 1 :(得分: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;
};

答案 2 :(得分:4)

我喜欢NickLarsen的答案,但我有一件事要补充:

不要让对象的私有字段在该对象之外更改。如果必须更改Room对象使用委派。也就是说如果Room采用SetFloorColor(Color _color);方法,那么您应该将House调用

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

答案 3 :(得分:2)

操作发生在房间,而不是房子。如果您可以通过房屋返回房间的不可变参考,然后可以操作,您就不会破坏OOP。

答案 4 :(得分:2)

虽然我喜欢NickLarsen的回答,但我会指出另一件事:房间不会自己着色(或涂漆)。该动作通常由画家完成,画家显然不是房间的成员。现在画家可以给整个房子上色,或者画家只能在一个房间里工作。

在这种情况下,我建议房间具有颜色属性,并且更改该颜色的行为由另一个对象在外部处理。

这个想法会建议Color属性必须是一个公共属性,并且你要将一个引用传递给要更改为Painter对象的房间。

答案 5 :(得分:0)

暴露私人成员会降低凝聚力并增加耦合。通常,您应该阻止这样的代码:

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

此代码的可维护性较差,违反了Law of Demeter