Hãy nói rằng tôi có một hệ thống phân cấp các Item
lớp : Rectangle, Circle, Triangle
. Tôi muốn có thể vẽ chúng, vì vậy khả năng đầu tiên của tôi là thêm một Draw()
phương thức ảo vào mỗi phương thức:
class Item {
public:
virtual ~Item();
virtual void Draw() =0;
};
Tuy nhiên, tôi muốn phân chia chức năng vẽ thành một thư viện Draw riêng trong khi thư viện Core chỉ chứa các biểu diễn cơ bản. Có một vài khả năng tôi có thể nghĩ ra:
1 - A DrawManager
lấy danh sách Item
s và phải sử dụng dynamic_cast<>
để tìm ra việc cần làm:
class DrawManager {
void draw(ItemList& items) {
FOREACH(Item* item, items) {
if (dynamic_cast<Rectangle*>(item)) {
drawRectangle();
} else if (dynamic_cast<Circle*>(item)) {
drawCircle();
} ....
}
}
};
Điều này không lý tưởng vì nó phụ thuộc vào RTTI và buộc một lớp phải nhận thức được tất cả các mục trong hệ thống phân cấp.
2 - Cách tiếp cận khác là trì hoãn việc rút ra trách nhiệm đối với ItemDrawer
hệ thống phân cấp ( RectangleDrawer
, v.v.):
class Item {
virtual Drawer* GetDrawer() =0;
}
class Rectangle : public Item {
public:
virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}
Điều này đạt được sự phân tách mối quan tâm giữa biểu diễn cơ sở của Vật phẩm và mã để vẽ. Vấn đề là các lớp Item phụ thuộc vào các lớp vẽ.
Làm cách nào tôi có thể tách mã bản vẽ này thành một thư viện riêng? Là giải pháp cho các Mục để trả về một lớp nhà máy của một số mô tả? Tuy nhiên, làm thế nào để xác định điều này để thư viện Core không phụ thuộc vào thư viện Draw?