访客与作文

时间:2017-01-09 07:36:42

标签: java design-patterns

正如我所看到的那样,访客设计模式与作品的工作方式非常相似。 在组合中,我将在类中保存一个接口成员,并在构造函数中传递接口的具体实现,然后将方法委托给它或在类中使用它。

在访问者设计模式中我还有一个接口的具体实现,我将它发送到visit方法,然后将访问方法委托给它。

要在代码中显示这种相似性,访问者将是:

VisitorInterface v = new ConcreteVisitor();
MyClass c = new MyClass();
c.visit(v);
VisitorInterface dv = new DifferentVisitor();
c.visit(dv);

组成将是:

SomeInterface i = new ConcreteImplementation();
MyClass c = new MyClass(i);
c.visit();  // called visit just to show the symmetry to visitor pattern
SomeInterface di = new DifferentImplementation();
c.changeReference(di);
c.visit(); 

我想听听你的想法,在哪些情况下,你更喜欢一个,为什么

3 个答案:

答案 0 :(得分:3)

组合是在对象之间表达 has-a 关系的手段,换句话说,是对对象的属性进行建模。一头牛角。注射对此不是必需的。访问者模式是一种对类型执行外部操作的方法。它们用于不同的目的并且在对象模型的不同部分上操作。为了回答你的问题,当情境逻辑要求具有属性的类型时,我更喜欢组合,而访客模式则用于组织代码以在不改变结构的情况下对类型的实例执行操作目标类型的,如该模式所记录的那样。

答案 1 :(得分:1)

  

"访客设计模式与作文工作方式非常相似。"

实际上并非如此。组合是对象创建的基本原则,如抽象,封装,多态等。它只是 有一个关系 AdapterCompositeDecorator模式是使用合成原则的完美示例。

访客模式是从基本编程原则推导出的高级解决方案。 Visitor背后的基本逻辑是基于不同子类类型的方法重载。

例如:您有一个名为 Bird 的基类或接口以及 子类Crow,Duck 和的 企鹅 即可。并且您希望某个客户端类的方法能够执行不同的w.r.t.子类的类型。即在这里假设,我想要一个 Hunter 类,其中 区分了Hunter.hunt()方法w.r.t的行为。无论是Crow,Duck还是Penguin

所以我的 Hunter 类看起来像这样。

public class Hunter{

    public void hunt(Crow crow){
        //crow hunting logic.
    }

    public void hunt(Duck duck){
        //duck hunting logic.
    }

    public void hunt(Penguin penguin){
        //penguin hunting logic.
    }

}

如果我喜欢这个,

Bird bird = new Duck();
Hunter hunter = new Hunter();

hunter.hunt(bird);

现在,此hunter.hunt();会自动导航到hunt(Duck duck)方法并执行。

我认为您理解构图原则与访客模式之间没有多大关系。

作为最后一点, 访客通常不是一个好的模式 。原因是,当你添加不同的新子类时,它会让你继续重载越来越多的方法。在我们的示例中,如果要添加像Pigeon,Eagle等新类,则必须添加方法hunt(Pigeon pigeon)hunt(Eagle eagle)。这将是一个特别大规模的可怕维护问题。所以如果只有在没有其他选择或没有反弹的情况下才使用它会更好。

答案 2 :(得分:0)

也许您应该考虑在哪里可以使用提到的模式来理解差异:

Composite
将对象组合成树结构以表示部分整体层次结构。对象组将以与对象的单个实例相同的方式处理。

绘图示例(来自java的swing库):绘图可以由图形基元组成(合成),例如线条,圆形,矩形,文本等。但是为了绘制我们操作复合材料的方式与操作原始对象的方式完全相同。

Visitor
允许在运行时将一个或多个操作应用于一组对象,从而将操作与对象结构分离。

基本思想是如何通过对象结构(对象结构可以是树,看起来类似于Composite)具有相同的机制,然后通过结构中的对象在每个步骤上我们可以有一个或多个操作,
在编译器中,AST是对象结构,访问者可以用来通过AST遍历并生成二进制代码,或XML输出或...

希望这有助于