контекст
Я использовал с иерархией объектов (дерево выражений) «псевдо» шаблон посетителя (псевдо, так как в нем не используется двойная диспетчеризация):
public interface MyInterface
{
void Accept(SomeClass operationClass);
}
public class MyImpl : MyInterface
{
public void Accept(SomeClass operationClass)
{
operationClass.DoSomething();
operationClass.DoSomethingElse();
// ... and so on ...
}
}
Этот дизайн был, однако, сомнительным, довольно удобным, так как количество реализаций MyInterface является значительным (~ 50 или более), и мне не нужно было добавлять дополнительные операции.
Каждая реализация уникальна (это другое выражение или оператор), а некоторые являются составными (т. Е. Узлами операторов, которые будут содержать другие операторы / конечные узлы).
Обход в настоящее время выполняется путем вызова операции Accept на корневом узле дерева, которая, в свою очередь, вызывает Accept на каждом из его дочерних узлов, что, в свою очередь ... и так далее ...
Но пришло время, когда мне нужно добавить новую операцию , например, красивую печать:
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);
}
}
Я в основном вижу два варианта:
- Сохраняйте тот же дизайн, добавляя новый метод для моей операции к каждому производному классу, за счет удобства обслуживания (не вариант, ИМХО)
- Используйте «истинный» шаблон Visitor за счет расширяемости (не вариант, так как я ожидаю, что в будущем будет реализовано больше реализаций ...), с более чем 50-ю перегрузками метода Visit, каждая из которых соответствует определенной реализации ?
Вопрос
Вы бы порекомендовали использовать шаблон Visitor? Есть ли другой шаблон, который может помочь решить эту проблему?
MyInterface
. Все ли эти классы имеют уникальную реализацию DoSomething
и DoSomethingElse
? Я не вижу, где ваш класс посетителей фактически пересекает иерархию - facade
в данный момент это больше похоже на ...