Disons que j'ai une hiérarchie de Item
cours: Rectangle, Circle, Triangle
. Je veux pouvoir les dessiner, donc ma première possibilité est d'ajouter une Draw()
méthode virtuelle à chacun:
class Item {
public:
virtual ~Item();
virtual void Draw() =0;
};
Cependant, je souhaite diviser la fonctionnalité de dessin en une bibliothèque Draw distincte tandis que la bibliothèque Core ne contient que les représentations de base. Il y a quelques possibilités auxquelles je peux penser:
1 - A DrawManager
qui prend une liste de Item
s et doit utiliser dynamic_cast<>
pour déterminer quoi faire:
class DrawManager {
void draw(ItemList& items) {
FOREACH(Item* item, items) {
if (dynamic_cast<Rectangle*>(item)) {
drawRectangle();
} else if (dynamic_cast<Circle*>(item)) {
drawCircle();
} ....
}
}
};
Ce n'est pas idéal car il repose sur RTTI et force une classe à être au courant de tous les éléments de la hiérarchie.
2 - L'autre approche consiste à reporter l'attribution de la responsabilité à une ItemDrawer
hiérarchie ( RectangleDrawer
, etc.):
class Item {
virtual Drawer* GetDrawer() =0;
}
class Rectangle : public Item {
public:
virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}
Cela permet de séparer les préoccupations entre la représentation de base des articles et le code de dessin. Le problème est que les classes d'objets dépendent des classes de dessin.
Comment puis-je séparer ce code de dessin dans une bibliothèque distincte? La solution consiste-t-elle pour les articles à renvoyer une classe d'usine d'une certaine description? Cependant, comment cela peut-il être défini afin que la bibliothèque Core ne dépende pas de la bibliothèque Draw?