Attualmente ho tre classi e rispettive interfacce e rispettivi builder:
-
Albero : la struttura dei dati (implementata in
SimpleTree) -
ProbabilityTree : è un
Treecon funzionalità aggiunte per selezionare casualmente nodi figlio e per regolare la probabilità di selezione di un nodo (implementata inProbabilityTreeImpl). -
DynamicTree : è un
ProbabilityTreeche crea dinamicamente nodi quando un nodo richiesto non esiste ancora.
Il codice cliente ha bisogno di Alberi che supportano sia la selezione casuale dei nodi, come fornita da ProbabilityTree , sia la struttura che cresce dinamicamente quando vengono richiesti nodi ancora inesistenti, come previsto da DynamicTree .
NOTA: Attualmente tutti e tre gli alberi sono immutabili dopo essere stati costruiti; per DynamicTree questo significa che i clienti non possono aggiungere o rimuovere nodi, ma la struttura stessa può cambiare automaticamente.
NOTA: vedi Github gist con le cinque classi Java per il codice.
Ci sono almeno due problemi con questo design:
-
DynamicTreeè derivato daProbabilityTree, mentre concepzionalmente queste due capacità non sono correlate (cioè ortogonali). - L'utilizzo dell'ereditarietà per l'aggiunta funzionale è spesso considerato "cattivo design" (correggimi se ho torto qui).
Un design alternativo sarebbe quello di disaccoppiare ProbabilityTree e DynamicTree usando qualcosa di simile al decoratore e / o al modello dell'adattatore. L'utilizzo del proxy dinamico di Java potrebbe consentire ai "decoratori" di estendere il interfaccia e che può decorare altri Tree s con interfacce estese; cioè:.
TreeDecorator implements InvocationHandler, ... {
Tree adapted;
...
Object invoke(Method method, Object[] args) {
if( «this class can/should handle method» ) {
return method.invoke(this, args);
} else if ( «this.adapted can/should handle method» ){
return method.invoke(adapted, args);
}
};
}
Ancora una volta ci sono alcuni problemi:
- L'utilizzo di
Proxyrende il codice più difficile da comprendere.
Che cosa devo fare? Utilizzare l'ereditarietà per estendere la funzionalità, utilizzare il proxy dinamico o qualcos'altro?