Kontext
Ich habe mit einer Hierarchie von Objekten (einem Ausdrucksbaum) ein "Pseudo" -Besuchermuster verwendet (Pseudo, da darin kein doppelter Versand verwendet wird):
public interface MyInterface
{
void Accept(SomeClass operationClass);
}
public class MyImpl : MyInterface
{
public void Accept(SomeClass operationClass)
{
operationClass.DoSomething();
operationClass.DoSomethingElse();
// ... and so on ...
}
}
Dieses Design war jedoch fragwürdig und recht komfortabel, da die Anzahl der Implementierungen von MyInterface erheblich ist (~ 50 oder mehr) und ich keine zusätzlichen Operationen hinzufügen musste.
Jede Implementierung ist eindeutig (es ist ein anderer Ausdruck oder Operator), und einige sind Verbundwerkstoffe (dh Operatorknoten, die andere Operator- / Blattknoten enthalten).
Das Durchlaufen wird derzeit ausgeführt, indem die Accept-Operation auf dem Stammknoten des Baums aufgerufen wird, der wiederum Accept auf jedem seiner untergeordneten Knoten aufruft, was wiederum ... und so weiter ...
Aber es ist an der Zeit, dass ich einen neuen Vorgang hinzufügen muss , z. B. hübsches Drucken:
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);
}
}
Grundsätzlich sehe ich zwei Möglichkeiten:
- Behalten Sie das gleiche Design bei und fügen Sie jeder abgeleiteten Klasse auf Kosten der Wartbarkeit eine neue Methode für meine Operation hinzu (keine Option, IMHO).
- Verwenden Sie das "echte" Besuchermuster auf Kosten der Erweiterbarkeit (keine Option, da ich davon ausgehe, dass weitere Implementierungen auf dem Weg sind ...) mit mehr als 50 Überladungen der Visit-Methode, die jeweils einer bestimmten Implementierung entsprechen ?
Frage
Würden Sie die Verwendung des Besuchermusters empfehlen? Gibt es ein anderes Muster, das zur Lösung dieses Problems beitragen könnte?
MyInterface
.. Haben alle diese Klassen eine eindeutige Implementierung von DoSomething
und DoSomethingElse
? Ich sehe nicht, wo Ihre Besucherklasse tatsächlich die Hierarchie durchquert - es sieht facade
im Moment eher wie eine aus .