Java访客模式扩展功能

时间:2011-12-01 15:07:44

标签: c# design-patterns visitor

我正在研究访客模式并遇到了这个有用的例子:https://stackoverflow.com/a/2604798/974594。这个帖子非常清楚,非常容易理解,我很难理解最后一部分,从这里开始:

  

话虽如此,访客通常是矫枉过正,他们有一个   趋势使API复杂化,并且它可能非常麻烦   为每种新行为定义一个新的访问者。

     

通常,应该使用类似继承的简单模式来代替   游客。例如,原则上我可以编写一个类:

class FruitPricer : IFruitVisitor
{
    public double Price { get; private set; }
    public void Visit(Orange fruit) { Price = 0.69; }
    public void Visit(Apple fruit) { Price = 0.89; }
    public void Visit(Banana fruit) { Price = 1.11; }
}
     

它有效,但与这个微不足道的修改相比有什么优势:

     

抽象类水果

{
    public abstract void Accept(IFruitVisitor visitor);
    public abstract double Price { get; }
}

我不知道他在这里说的是什么。我的意思是,如果他现在想要实现“价格”功能,必须更改/添加到现有代码中(基于此模式方法)?=

2 个答案:

答案 0 :(得分:2)

你提到的答案错过了访客的大部分内容。它说“访客习惯于在不牺牲类型安全的情况下实施类型测试”,这是完全错误的。 GOF书中说“访问者可以在不改变其运行元素的类别的情况下定义新操作”。访问者当然可以用于测试除类型之外的对象,以及对不涉及测试的对象执行操作。

“访客过度杀戮”经常被说明,但通常会说人们试图将访客用于其不适合的事情,然后发现 - 这是一种惊喜 - 它并不适用于它。

海报的正确之处在于,他们引用的第二段代码是实现功能的一种更简单的方法,但它忽略了访问者在您不想修改Fruit类时的意图。 / p>

答案 1 :(得分:1)

为每个子类添加特定于类的价格实现。

关键是有时候Visitor有点矫枉过正,而且可以用抽象的方式添加功能。

现在,Fruit Price是否合理是一个不同的问题。 ItemItem价格,FruitFruitItem成为{{1}}的子类,或者他们可能更有意义'复合,或者......