Estende le funzionalità di una classe: ereditarietà o proxy dinamico di java

2

Attualmente ho tre classi e rispettive interfacce e rispettivi builder:

  • Albero : la struttura dei dati (implementata in SimpleTree )
  • ProbabilityTree : è un Tree con funzionalità aggiunte per selezionare casualmente nodi figlio e per regolare la probabilità di selezione di un nodo (implementata in ProbabilityTreeImpl ).
  • DynamicTree : è un ProbabilityTree che 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:

  1. DynamicTree è derivato da ProbabilityTree , mentre concepzionalmente queste due capacità non sono correlate (cioè ortogonali).
  2. 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:

  1. L'utilizzo di Proxy rende il codice più difficile da comprendere.

Che cosa devo fare? Utilizzare l'ereditarietà per estendere la funzionalità, utilizzare il proxy dinamico o qualcos'altro?

    
posta Kasper van den Berg 14.08.2012 - 15:07
fonte

1 risposta

1

Posso pensare a 3 opzioni ragionevoli, a seconda di cosa hai realmente bisogno (proprio ora) e di quanto sia complesso il tuo codice.

(Quello che attualmente chiamate DynamicTree , chiamo DynamicProbabilityTree )

  1. Se l'unica cosa di cui hai veramente bisogno è una DynamicProbabilityTree , e ritieni che il tuo codice sia abbastanza semplice da stare in una classe, inserisci tutto il codice in DynamicProbablityTree e sbarazzati delle altre classi .

  2. Se l'unica cosa di cui hai veramente bisogno è una DynamicProbabilityTree , ma ritieni che il codice sia troppo complesso per rientrare in una classe, mantieni il codice per la struttura ad albero in SimpleTree e metti la dinamica e codice di probabilità in DynamicProbabilityTree . Vorrei raccomandare che DynamicProbabilityTree contenga e deleghi ad un albero invece di ereditare; anche l'ereditarietà funzionerebbe.

  3. Se hai davvero bisogno di un SimpleTree , ProbabilityTree (che non è dinamico), DynamicTree (che non fa probabilità) e DynamicProbabilityTree , usa il pattern Decoratore.

risposta data 16.08.2012 - 23:54
fonte

Leggi altre domande sui tag