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

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

1) Phòng không thể tồn tại mà không có nhà, căn nhà "có phòng". (thành phần)
2) Một cách khác để tô màu phòng sẽ là có một phương pháp trong Nhà mà sẽ gọi phương pháp ColorRoom trong phòng nhưng sau đó điều này là nhiều phái đoàn. (tôi muốn tránh điều này)

Cách duy nhất tôi thấy là ở trên nhưng có vẻ như quay lại tham chiếu đến thành viên riêng tư đang vi phạm OOP. Đây có phải là thiết kế tốt không?Thành phần tinh khiết có phá vỡ các khái niệm OOP không?

Trả lời

4

Nhìn chung, bạn tốt, vì tự mình tạo m_room biến thành viên - nó không yêu cầu người tiêu dùng gọi một thứ gì đó sau khi khởi tạo. Điều này theo mô hình mà một mục có thể sử dụng ngay lập tức sau khi instantiation (nó không yêu cầu các hành động đặc biệt như thiết lập một phòng hoặc bất cứ điều gì).

Tôi có một số nhỏ nit-pickings:

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

Tính năng này hoạt động tốt và giải thích ngắn gọn, xem câu trả lời của tôi. –

+0

Lưu ý rằng 'virtual' đề cập đến * ghi đè * và không * quá tải *. – Dario

+0

Bạn có thể ghi đè lên một hàm không thừa hưởng? Thứ hai, nếu người dùng muốn sửa đổi phòng có vẻ như họ cần phải gọi một phương pháp của Nhà mà lần lượt sẽ gọi phương pháp phòng, tương tự như đoàn. –

2

Các hoạt động đang diễn ra trên căn phòng, và không nhà. Nếu bạn có thể trả lại một tài liệu tham khảo bất biến cho căn phòng thông qua ngôi nhà mà sau đó có thể được vận hành, bạn sẽ không phá vỡ OOP.

5

Điều là bạn không tiết lộ rõ ​​ràng thành viên riêng tư của mình. API của bạn chỉ cho thấy một phương pháp để có được một căn phòng, và người tiêu dùng không biết nếu Nhà đang tạo ra căn phòng đó, trả lại một cái gì đó được tổ chức trong một lĩnh vực tư nhân, hoặc nhận được phòng từ một dịch vụ web. Đó là OO vững chắc.

+2

Điều này rất quan trọng, nhưng xin lưu ý rằng nó thường là thiết kế xấu để cho phép các lực lượng bên ngoài sửa đổi trạng thái đối tượng của bạn mà không cần xác nhận. –

4

Tôi thích câu trả lời của NickLarsen nhưng tôi có một điều để thêm:

Đừng để một lĩnh vực riêng của một đối tượng được thay đổi bên ngoài của đối tượng đó. Nếu bạn phải thay đổi ủy quyền sử dụng đối tượng Room. Đó là nếu Room có một phương pháp SetFloorColor(Color _color); thì bạn nên đưa vào House một cuộc gọi đến

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

Mặc dù tôi thích câu trả lời NickLarsen, tôi sẽ chỉ ra một điều khác: Phòng không màu (hoặc sơn) mình. Hành động đó thường được thực hiện bởi một họa sĩ, mà rõ ràng không phải là một thành viên của một căn phòng. Bây giờ một họa sĩ có thể tô màu toàn bộ ngôi nhà hoặc họa sĩ chỉ có thể làm việc trên một phòng.

Tôi đề xuất trong trường hợp này phòng có thuộc tính màu và hành động thay đổi màu đó được xử lý bên ngoài bởi một đối tượng khác.

Ý tưởng này sẽ gợi ý rằng thuộc tính Màu phải là thuộc tính công khai và bạn sẽ chuyển tham chiếu đến phòng được thay đổi đối tượng Painter.

0

Hiển thị các thành viên riêng sẽ giảm bớt sự gắn kết và tăng khả năng kết nối. Nói chung, bạn nên ngăn chặn mã như sau:

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

Mã này ít bảo trì và vi phạm Law of Demeter.

Các vấn đề liên quan