Powiedzmy mam hierarchię Item
klas: Rectangle, Circle, Triangle
. Chcę móc je narysować, więc moją pierwszą możliwością jest dodanie wirtualnej Draw()
metody do każdej z nich:
class Item {
public:
virtual ~Item();
virtual void Draw() =0;
};
Chcę jednak podzielić funkcję rysowania na osobną bibliotekę Draw, podczas gdy biblioteka Core zawiera tylko podstawowe reprezentacje. Jest kilka możliwości, o których mogę myśleć:
1 - A, DrawManager
który bierze listę Item
si i musi użyć, dynamic_cast<>
aby dowiedzieć się, co zrobić:
class DrawManager {
void draw(ItemList& items) {
FOREACH(Item* item, items) {
if (dynamic_cast<Rectangle*>(item)) {
drawRectangle();
} else if (dynamic_cast<Circle*>(item)) {
drawCircle();
} ....
}
}
};
Nie jest to idealne, ponieważ opiera się na RTTI i zmusza jedną klasę do bycia świadomym wszystkich pozycji w hierarchii.
2 - Drugim podejściem jest odłożenie odpowiedzialności na ItemDrawer
hierarchię ( RectangleDrawer
itp.):
class Item {
virtual Drawer* GetDrawer() =0;
}
class Rectangle : public Item {
public:
virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}
Uzyskuje się to rozdzielenie obaw między podstawową reprezentacją przedmiotów a kodem do rysowania. Problem polega jednak na tym, że klasy przedmiotów są zależne od klas rysunku.
Jak mogę oddzielić ten kod rysunkowy do osobnej biblioteki? Czy rozwiązaniem jest zwrócenie Przedmiotów do klasy fabrycznej określonego opisu? Jak można to jednak zdefiniować, aby biblioteka Core nie była zależna od biblioteki Draw?