gpt4 book ai didi

design-patterns - 为什么我们需要访问者设计模式中的访问方法?

转载 作者:行者123 更新时间:2023-12-04 07:15:16 25 4
gpt4 key购买 nike

为什么我们需要两者acceptvisit在访客 DP 中的功能?如果我们举一个典型的例子:

class Visitor {
visit(A a) { }
visit(B b) { }
}

interface Element {
accept(Visitor v);
}

class A implements Element {
accept(Visitor v) {
v.visit(this); // will call visit(A)
}
}

class B implements Element {
accept(Visitor v) {
v.visit(this); // will call visit(B)
}
}

要使用访问者 DP,我们在某处有一个实例 vVisitor , 和一个实例 eElement ,我们这样做:

e.visit(v)

简单调用

v.visit(e)

那么为什么我们不能简单地进行第二次调用并绕过中介函数呢?因为我认为 GoF 并不愚蠢,所以我想我漏掉了什么。这是什么?

最佳答案

Here是访问者模式的极好引用,其中提到了以下内容:

When the accept() method is called in the program, its implementation is chosen based on both:

  • The dynamic type of the element.
  • The static type of the visitor.

When the associated visit() method is called, its implementation is chosen based on both:

  • The dynamic type of the visitor.
  • The static type of the element as known from within the implementation of the accept() method, which is the same as the dynamic type of the element. (As a bonus, if the visitor can't handle an argument of the given element's type, then the compiler will catch the error.)

Consequently, the implementation of the visit() method is chosen based on both:

  • The dynamic type of the element.
  • The dynamic type of the visitor.

然后他们继续提到以下内容:

This effectively implements double dispatch...

In this way, a single algorithm can be written for traversing a graph of elements, and many different kinds of operations can be performed during that traversal by supplying different kinds of visitors to interact with the elements based on the dynamic types of both the elements and the visitors.

在Java汽车例子中可以看到:

class Car implements CarElement {
CarElement[] elements;
// ...
public void accept(CarElementVisitor visitor) {
for(CarElement elem : elements) {
elem.accept(visitor);
}
visitor.visit(this);
}
}

因此,总而言之,在您的示例中,您不会从原始 DP 实现中获得太多好处,但如果示例更复杂,例如它是 Composite使用 Element 的多个内部实现(如上面的 Java 汽车示例),然后它可以将访问者行为应用于其部分或全部内部元素。

根据对您原始问题的评论,此模式分为两部分:

  1. 该模式的最初动机:访问复杂的对象结构并在不更改被访问的类接口(interface)的情况下对其执行操作。
  2. 该模式是如何实现的:正如您提到的那样,它是双重分派(dispatch)。

我强烈推荐以下设计模式书籍,因为它确实简化了许多概念。 GoF 的书有时太学术了。

Head First Design Patterns

根据这本书,以下是使用 Visitor 的优缺点:

(在所用示例的上下文中)

优点

  • 允许您在不更改结构本身的情况下向复合结构添加操作
  • 添加新操作相对容易
  • 访客执行的操作代码是集中的

缺点

  • 当使用 Visitor 时,复合类的封装被破坏。
  • 因为涉及到遍历函数,所以对Composite结构的改动比较困难

关于design-patterns - 为什么我们需要访问者设计模式中的访问方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11722352/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com