语境
我一直在使用对象层次结构(一个表达式树)使用“伪”访问者模式(伪,因为它不使用双调度):
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);
}
}
我基本上看到两个选择:
- 保持相同的设计,在每个派生类中为我的操作添加一个新方法,但以可维护性为代价(恕我直言,这不是一种选择)
- 使用“真正的”访问者模式,但要牺牲可扩展性(这不是一个选择,我希望这会带来更多的实现...),并且Visit方法有大约50多个重载,每个重载都匹配一个特定的实现?
题
您会使用“访客”模式来建议使用吗?还有其他模式可以帮助解决此问题吗?
1
也许装饰连锁店会更合适?
—
MattDavey 2012年
一些问题:这些实现有何不同?层次结构是什么?它总是相同的结构吗?您是否总是需要以相同的顺序遍历结构?
—
jk。
@MattDavey:所以您会建议每个实现和操作使用一个装饰器?
—
T. Fabre 2012年
@ T.Fabre很难说。有50+实现者
—
MattDavey
MyInterface
..做所有这些类都有一个独特的实施DoSomething
和DoSomethingElse
?我没有看到你的访问者类实际上遍历层次-它看起来更像是facade
此刻..
也是什么版本的C#。你有lambdas吗?还是linq?在您的处置
—
JK。