【问题标题】:Can the Visitor Pattern take additional parameters访问者模式可以带附加参数吗
【发布时间】:2014-05-06 09:59:09
【问题描述】:

在实现访问者模式时,向 Accept 和 Visit 方法添加额外的参数是不是一个坏主意?我从未见过任何这样做的例子,但也没有提到这是一个坏主意。

我想在我的域模型中使用这种模式,但是除了实体本身之外还需要其他参数。

例如 -

public interface ISomethingVisitor
{
    void Visit(Foo foo, int p1, int p2);
}

public interface ISomethingVisitable
{
    void Accept(ISomethingVisitor visitor, int p1, int p2);
}

【问题讨论】:

  • 而p1、p2对于整个访问都一样?
  • 嗨@weston 是的,他们是。所有子类每次访问都需要相同的参数集。
  • 如果访问/接受只是一个引用初始化器,那么您可以向访问者添加额外的方法(带参数)来处理这个引用。将此视为随意阅读元素的权利。

标签: c# design-patterns domain-driven-design visitor-pattern


【解决方案1】:

我会说这是个坏主意。对于这个访问者来说它可能工作得很好,但是当另一个访问者需要更多/不同的参数时会发生什么?如果p1p2不改,可以在施工时交给访客:

public class MyVisitor : ISomethingVisitor
{
    private int p1;
    private int p2;

    public MyVisitor(int p1, int p2)
    {
       _p1 = p1;
       _p2 = p2;
    }

    public void Visit(Foo foo)
    {
        //got access to _p1, _p2 here 
    }
}

【讨论】:

  • 谢谢@weston。出于好奇 - 这是常见的做法.. 为访问者实现添加额外的属性和东西?
  • 另外,您提到在实现新访问者时可能会出现问题。但在这种情况下,我们不会为每个访问者创建新的 Accept 方法吗?
  • 我的意思是您可以添加一个新的ISomethingVisitor 而无需更改任何其他内容。即使新的ISomethingVisitor 实现需要p3
  • 是的,我会说向访问者注入值/对象是完全正常的,这样它就可以完成工作。例如,访问者将有关每个访问项目的信息记录到文本日志文件中。这需要知道文件的路径,除非您打算对其进行硬编码(yuk)。或者更好的是,您可以注入一个记录日志的对象。
  • 这样想:访问者模式是关于双动态调度的。这真的伴随着参数的数量:“this”和“Foo”。而且,访问也是一个界面。每个参数都为这种设计模式增加了指数级的复杂性。我同意韦斯顿的观点:这是不明智的
【解决方案2】:

我正在做与此类似的事情,但使用的是 Java。我面临着同样的问题,我想将一些“访问上下文”信息传递给访问,但我的问题是“访问者”是无状态的,所以只创建了一个访问者来服务所有线程(即:所有信息必须通过参数)。我不想涉足线程本地变量的业务。

所以,对于你的界面设计,我建议如下:

public interface ISomethingVisitor
{
    void Visit(Foo foo, VisitOptions params);
}

public interface ISomethingVisitable
{
    void Accept(ISomethingVisitor visitor, VisitOptions params);
}

通过这种方式,您可以使用 2 个字段定义您的 VisitOptions 参数:p1p2,如果您想稍后添加一些参数,将它们添加到您的 VisitOptions 类没有问题...任何现有代码只会忽略它们的存在。如果您通过更改/删除参数来修改 VisitOptions,则会遇到问题,但这是典型的向后兼容性问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    相关资源
    最近更新 更多