Скажімо , у мене є ієрархія Item
класів: Rectangle, Circle, Triangle
. Я хочу вміти їх малювати, тому моя перша можливість - додати віртуальний Draw()
метод до кожного:
class Item {
public:
virtual ~Item();
virtual void Draw() =0;
};
Однак я хочу розділити функцію малювання на окрему бібліотеку Draw, тоді як основна бібліотека містить лише основні подання. Є кілька можливостей, про які я можу придумати:
1 - Таблиця, 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?