Contesto
Ho usato con una gerarchia di oggetti (un albero delle espressioni) un modello di visitatore "pseudo" (pseudo, poiché in esso non viene utilizzato il doppio dispacciamento):
public interface MyInterface
{
void Accept(SomeClass operationClass);
}
public class MyImpl : MyInterface
{
public void Accept(SomeClass operationClass)
{
operationClass.DoSomething();
operationClass.DoSomethingElse();
// ... and so on ...
}
}
Questo design è stato, comunque, discutibile, abbastanza comodo poiché il numero di implementazioni di MyInterface è significativo (~ 50 o più) e non ho avuto bisogno di aggiungere ulteriori operazioni.
Ogni implementazione è unica (è un'espressione o un operatore diverso) e alcuni sono compositi (cioè nodi di operatori che conterranno altri nodi operatore / foglia).
Traversal viene attualmente eseguito chiamando l'operazione Accept sul nodo radice dell'albero, che a sua volta chiama Accept su ciascuno dei suoi nodi figlio, che a sua volta ... e così via ...
Ma è giunto il momento in cui devo aggiungere una nuova operazione , come la stampa carina:
public class MyImpl : MyInterface
{
// Property does not come from MyInterface
public string SomeProperty { get; set; }
public void Accept(SomeClass operationClass)
{
operationClass.DoSomething();
operationClass.DoSomethingElse();
// ... and so on ...
}
public void Accept(SomePrettyPrinter printer)
{
printer.PrettyPrint(this.SomeProperty);
}
}
Praticamente vedo due opzioni:
- Mantenere lo stesso design, aggiungendo un nuovo metodo per la mia operazione a ciascuna classe derivata, a spese della manutenibilità (non un'opzione, IMHO)
- Usa il modello "vero" di Visitatori, a scapito dell'estensibilità (non un'opzione, poiché mi aspetto di avere più implementazioni in arrivo ...), con circa 50+ sovraccarichi del metodo Visit, ognuno corrispondente a un'implementazione specifica ?
Domanda
Consiglieresti di usare il modello Visitatore? C'è qualche altro modello che potrebbe aiutare a risolvere questo problema?
MyInterface
.. tutte queste classi hanno un'implementazione unica di DoSomething
e DoSomethingElse
? Non vedo dove la tua classe di visitatori attraversi effettivamente la gerarchia - sembra più simile a un facade
al momento ..