Diciamo che ho una gerarchia delle classi Item
: Rectangle, Circle, Triangle
. Voglio essere in grado di disegnarli, quindi la mia prima possibilità è aggiungere un metodo virtuale Draw()
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à a cui posso pensare:
1 - Un DrawManager
che prende una lista di Item
s e 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 è il rinvio della responsabilità di disegno a una gerarchia ItemDrawer
( RectangleDrawer
, ecc.):
class Item {
virtual Drawer* GetDrawer() =0;
}
class Rectangle : public Item {
public:
virtual Drawer* GetDrawer() {return new RectangleDrawer(this); }
}
Ciò ottiene la separazione delle preoccupazioni tra la rappresentazione di base degli Elementi e il codice per il disegno. Il problema però è che le classi Item dipendono dalle classi del disegno.
Come posso separare questo codice di disegno in una libreria separata? La soluzione per gli articoli restituisce una classe factory di qualche descrizione? Tuttavia, come può essere definito in modo tale che la libreria Core non dipenda dalla libreria Draw?