L'approccio a tre classi è allettante perché rispecchia la corretta progettazione del database, mappando una classe in una tabella. È molto elegante da un progetto concettuale di alto livello, ma di solito è eccessivamente complesso in un'implementazione reale, e quindi raramente utilizzato nelle API più diffuse. Di solito le relazioni sono descritte da entrambi degli oggetti coinvolti, come nel evento e utente API.
Ad esempio, guarda i toolkit della GUI con i contenitori pieni di widget. Chiama container.add(widget)
, che internamente chiama qualcosa come widget.setContainer(container)
. Una volta stabilita la relazione tra widget del contenitore, a volte puoi chiamare container.getWidgets()
e a volte puoi chiamare widget.getContainer()
.
Ora considera come sarebbe implementato con un terzo oggetto ContainerWidget
. Ogni volta che volevi creare un'associazione, sarebbe come questa:
containerWidget = new ContainerWidget(container, widget);
container.addContainerWidget(containerWidget);
widget.setContainerWidget(containerWidget);
Per ottenere il contenitore di un widget dovrebbe assomigliare a questo:
widget.getContainerWidget().getContainer();
Alla fine qualcuno si arrabbia con la digitazione, e crea solo un widget.getContainer()
.
Ottenere tutti i widget per un contenitore è ancora più complicato:
containerWidgets = container.getContainerWidgets();
for (containerWidget in containerWidgets)
widgets.append(containerWidget.getWidget());
Alla fine qualcuno si arrabbierà e creerà un container.getWidgets()
. Poi alla fine qualcuno noterà che, poiché abbiamo già quei metodi comunque, e piuttosto che ricostruire l'elenco ogni volta che viene chiamato, sarebbe molto più semplice solo memorizzare un elenco di widget nel contenitore e un puntatore al contenitore nel widget .
Vedi dove sto andando con questo? O si finisce con una complessità inutile, o alla fine si semplifica fino alla soluzione a due classi.
L'eccezione alla regola è quando è necessario descrivere gli attributi della relazione stessa. Ad esempio, una relazione sponsale tra due persone non merita una terza classe. Hai appena inserito un puntatore Person
nella classe Person
in modo che punti al coniuge corrente. Tuttavia, una relazione matrimoniale merita una terza classe, perché i matrimoni hanno luoghi, date di inizio, date di fine, ecc. Che descrivono aspetti della relazione diversi dal semplice fatto che esiste.