问题标签 [visitor-pattern]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
9 回答
1614 浏览

java - 您什么时候决定为您的对象使用访问者?

我一直认为一个对象需要数据和消息才能对其进行操作。你什么时候想要一个对象外在的方法?您遵循什么经验法则来接待访客?这是假设您完全控制了对象图。

0 投票
4 回答
3589 浏览

design-patterns - 命令模式与访问者模式

允许访问者修改接收者的状态通常是可以接受的,还是应该改为命令模式?

0 投票
2 回答
2095 浏览

c++ - 访问者和模板化虚拟方法

访问者模式的典型实现中,类必须考虑基类的所有变体(后代)。在很多情况下,访问者中的相同方法内容应用于不同的方法。在这种情况下,模板化的虚拟方法是理想的,但目前还不允许这样做。

那么,模板化的方法可以用来解析父类的虚方法吗?

给定(基础):

现在奠定了基础,这就是踢球者的用武之地(模板化方法):

故意在方法声明Visitor_Cout中不包含关键字。virtual方法签名的所有其他属性都与父声明(或规范)匹配。

总体而言,这种设计允许开发人员实现仅因目标对象(接收访问的对象)类型不同而不同的通用访问功能。上面的实现是我对派生访问者实现未实现可选方法时的警报的建议。

这在 C++ 规范中合法吗?

(我不相信有人说它可以与编译器XXX一起使用。这是一个针对通用语言的问题。)

0 投票
4 回答
284 浏览

java - 需要帮助使这些类使用访问者模式和泛型

我需要帮助来生成和实现访问者模式。我们正在使用大量,instanceof这很痛苦。我确信它可以修改,但我不知道该怎么做。

基本上我们有一个接口ProcessData

现在我们有一个ProcessDataGeneric实现的类ProcessData

现在是一个检索 ProcessData 的新接口

现在是一个实现包装器的通用抽象类,因此可以检索 ProcessData

现在实施

相似地

现在当我使用这些类时,我总是需要做instanceof

我知道有更好的方法可以做到这一点,但我不知道如何利用泛型和访问者模式。任何帮助是极大的赞赏。

更新

我想补充一点,这些类只是一个更大的实现的片段。ProcessDataandProcessDataGeneric是代表之外的东西(等等ProcessDataMotorferdsel)。代表们都在扩展ProcessDataCommon

我同意重构可能是最好的做法,但这是已有 2 年历史的生产代码,重构成本很高(时间、测试等)。不过,我愿意这样做。

更新#2

我试图启动通用进程,但是出现编译错误。这就是它现在的样子。

我在线得到编译错误:unwrapped = new ProcessDataGeneric<ProcessDataMotorferdsel>(this);

[javac] ProcessDataMotorferdsel.java:52: incompatible types [javac] found : ProcessDataGeneric<ProcessDataMotorferdsel> [javac] required: ProcessData<ProcessDataCommon> [javac]

我无法确定该错误消息的正面或反面。ProcessDataMotorferdsel 类扩展了 ProcessDataCommon,因此 IMO 它应该可以工作。

0 投票
3 回答
14777 浏览

c++ - 需要一个虚拟模板成员解决方法

我需要编写一个实现访问者设计模式的程序。问题是基本访问者类是一个模板类。这意味着 BaseVisited::accept() 将模板类作为参数,并且由于它使用“this”并且我需要“this”来指向对象的正确运行时实例,因此它也需要是虚拟的。
我想知道有没有办法解决这个问题。

0 投票
2 回答
294 浏览

java - Java 抽象访问者 - 保证成功?如果是这样,为什么?

我正在处理休眠,试图通过使用访问者模式找出代理实例背后的运行时类。然后我想出了一个AbstractVisitable方法,但我想知道它是否总是会产生正确的结果。

考虑以下代码:

这使得 a ConcreteVisitablewhich 从 继承accept方法AbstractVisitable。在 c++ 中,我认为这是有风险的,因为this在 AbstractVisitable 中可能引用AbstractVisitable::this,而不是ConcreteVisitable::this。我担心某些情况下的代码会打印class AbstractVisible. 然而,上面的代码输出class ConcreteVisitable,即使我将真实类型隐藏在动态代理后面(我能想到的最困难的情况)。上面的抽象访问者方法是否可以保证工作,或者这种方法是否存在一些缺陷?

thisJava 中关于指针的保证是什么?

0 投票
5 回答
822 浏览

c++ - 苹果、橙子和指向最衍生的 c++ 类的指针

假设我有一堆水果:

以及对所述水果起作用的一些多态函数:

好,等一下。停在那儿。请注意,任何理智的人都会让 Eat() 成为 Fruit 类的虚拟成员函数。但这不是一个选择,因为我不是一个理智的人。另外,我不想在我的水果类的头文件中使用 Pesticide*。

可悲的是,我接下来想要做的正是成员函数和动态绑定所允许的:

很明显,这里的问题是我们传递给 Eat() 的指针将是 Fruit*,而不是 Apple* 或 Orange*,因此没有东西会被吃掉,我们都会非常饿。

所以我真正想做的不是这个:

这是:

但据我所知,这种魔法并不存在,除了可能是一个充满了对 dynamic_cast 调用的讨厌的大 if 语句的形式。

那么是否有一些我不知道的运行时魔法?或者我应该实现和维护一个充满动态转换的大麻烦 if 语句?还是我应该接受它,放弃思考如何在 Ruby 中实现它,并让一点 Pesticide 进入我的水果头?

更新:与其做人为的只吃功能和杀虫剂,不如假设我只是不想把吃放在水果里,因为它没有意义。会吃自己的水果?普肖。相反,我需要一个带有 Eat 函数的 Eater 类,使用不同的代码来吃每种水果,以及一些默认代码,以防它是食客无法识别的水果:

但同样,这不起作用,C++ 中的直接解决方案似乎是对 dynamic_cast 的一堆调用。

但是,正如其中一个答案所暗示的那样,可能还有另一个聪明的解决方案。如果 Fruits 使用 MustPeel() 和 MustWash() 之类的函数暴露出对食客很重要的品质会怎样?然后你可以用一个 Eat() 函数来解决......

更新: Daniel Newby 指出,使用 Visitor 也可以解决所提出的问题……但这需要一些语义倒立(Fruit::use 或 Fruit::beEaten?)。

虽然我想接受几个答案,但我认为 psmears 的答案实际上是未来读者的最佳答案。感谢大家。

0 投票
0 回答
284 浏览

visitor-pattern - 访客模式缺少参数

我确定这一定是访问者模式的常见问题,所以我想看看是否有标准解决方案。

你怎么能重新编码一个树遍历,其中方法被内置到树类本身中,比如说

到使用访问者的代码中。想到的两个解决方案是

或将参数添加到 accept(Visitor&) 和 visit() 方法本身。但这并不比类中内置的原始遍历更好。

另一个问题是,如果每个内置遍历方法都采用不同的参数,或者一些返回值而另一些没有,或者它们不都返回相同的类型,会发生什么?

0 投票
2 回答
4248 浏览

c++ - 访客模式如何避免向下转型

任何人都可以在之前和之后显示示例代码以避免访问者模式代码的向下转换吗?

谢谢。

0 投票
2 回答
11501 浏览

c++ - 什么是单发和双发?

我已经编写了如下的访问者模式,但我不明白什么是单次和双次调度。AFAIK,单调度是调用基于调用者类型的方法,而双调度是调用基于调用者类型和参数类型的方法。

我猜双重分派发生在单类层次结构中,但为什么访问者类有两个类层次结构,但它仍然被认为是双重分派。

请使用我提供的示例代码进行解释。

AFAIK,第一次调度发生在调用接受的对象上,第二次调度发生在调用访问方法的对象上。

谢谢。