Скажем , у меня есть иерархия Item
классов: Rectangle, Circle, Triangle
. Я хочу иметь возможность рисовать их, поэтому моя первая возможность - добавить виртуальный Draw()
метод к каждому:
class Item {
public:
virtual ~Item();
virtual void Draw() =0;
};
Однако я хочу разделить функциональность рисования на отдельную библиотеку Draw, в то время как библиотека Core содержит только основные представления. Есть несколько возможностей, о которых я могу подумать:
1 - A, DrawManager
который берет список Item
s и должен использовать, dynamic_cast<>
чтобы решить, что делать:
class DrawManager {
void draw(ItemList& items) {
FOREACH(Item* item, items) {
if (dynamic_cast<Rectangle*>(item)) {
drawRectangle();
} else if (dynamic_cast<Circle*>(item)) {
drawCircle();
} ....
}
}
};
Это не идеально, так как он опирается на RTTI и заставляет один класс быть в курсе всех элементов в иерархии.
2 - Другой подход - отложить привлечение ответственности к ItemDrawer
иерархии ( RectangleDrawer
и т. Д.):
class Item {
virtual Drawer* GetDrawer() =0;
}
class Rectangle : public Item {
public:
virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}
Это позволяет разделить проблемы между базовым представлением Предметов и кодом для рисования. Проблема, однако, в том, что классы Item зависят от классов рисования.
Как я могу выделить этот код для рисования в отдельную библиотеку? Является ли решение для Предметов вернуть фабричный класс некоторого описания? Однако как это можно определить, чтобы библиотека Core не зависела от библиотеки Draw?