Diciamo che ho una gerarchia di Item
classi: Rectangle, Circle, Triangle
. Voglio essere in grado di disegnarli, quindi la mia prima possibilità è aggiungere un Draw()
metodo virtuale a ciascuno:
class Item {
public:
virtual ~Item();
virtual void Draw() =0;
};
Tuttavia, voglio dividere la funzionalità di disegno in una libreria Draw separata mentre la libreria Core contiene solo le rappresentazioni di base. Ci sono un paio di possibilità che mi vengono in mente:
1 - A DrawManager
che prende un elenco di se Item
deve usare dynamic_cast<>
per capire cosa fare:
class DrawManager {
void draw(ItemList& items) {
FOREACH(Item* item, items) {
if (dynamic_cast<Rectangle*>(item)) {
drawRectangle();
} else if (dynamic_cast<Circle*>(item)) {
drawCircle();
} ....
}
}
};
Questo non è l'ideale in quanto si basa su RTTI e impone a una classe di essere a conoscenza di tutti gli elementi nella gerarchia.
2 - L'altro approccio consiste nel rinviare la responsabilità di attirare una ItemDrawer
gerarchia ( RectangleDrawer
, ecc.):
class Item {
virtual Drawer* GetDrawer() =0;
}
class Rectangle : public Item {
public:
virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}
Ciò consente di separare le preoccupazioni tra la rappresentazione di base degli Articoli e il codice per il disegno. Il problema però è che le classi di oggetti dipendono dalle classi di disegno.
Come posso separare questo codice di disegno in una libreria separata? La soluzione per gli articoli è di restituire una classe di fabbrica con qualche descrizione? Tuttavia, come può essere definito in modo tale che la libreria Core non dipenda dalla libreria Draw?