问题标签 [double-dispatch]
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.
c++ - Double dispatch and factory pattern
I've got the following code currently (not working):
My goal is to use a factory pattern and avoid the creation of a new object if in a list I've got already that object. I tried to use a double dispatch pattern but it isn't easy to apply in this case. How can I do?
Edit: Since the code is used in a "critical" path, I want to avoid RTTI like dynamic_cast and so on.
c++ - 当我事先不知道所有的类时,如何实现双重调度?
我有一个(可能)有很多子类的基类,我希望能够比较基类的任何两个对象是否相等。我试图在不调用亵渎的 typeid 关键字的情况下做到这一点。
我知道编写的代码失败了,因为equalBounce() 中的lhs 是Base*,所以它甚至不知道采用A* 的equalCheck() 版本。但我不知道该怎么办。
c++ - 双重调度的循环依赖
我正在尝试实现双重调度模式,但我得到了一个循环依赖,我无法通过前向声明解决(因为它已在此问题链接中解决)。
下面是我的问题的一个例子:
标题 1:
标题 2:
我无法在标题 2 中转发声明Boundary
和,因为我需要一个完整的类型才能使用. 有什么建议可以解决这个问题吗?Blockage
boost::unordered_set
smalltalk - Double dispatch in Pharo
Could someone please explain the process of double dispatch in Pharo 4.0 with Smalltalk? I am new to Smalltalk and am having difficulty grasping the concept, since it is implemented very differently in Java as compared to Smalltalk. It will be very helpful if some one could explain it with an example.
c# - 根据另一个对象的类型选择/使用具有通用参数的接口实现
我正在开发一个处理事件的系统:
每个事件都有一个特定的处理程序
到目前为止,一切都非常简单。但是,我想为正确的事件创建使用正确事件处理程序的类。
到目前为止,我想出了以下方法:
这个解决方案有效,但我必须使用两种动态类型,这让我很担心。我想我可能做出了错误的设计决定,但我想不出其他架构/模式可以摆脱这些动态。
所以我的问题归结为:如何选择和使用具有通用性且运行时自省最少的接口的正确实现?
注意我更喜欢 IEvent 和 IEventHandler 实现完全不知道这个过程的解决方案
c# - 没有动态的稀疏双重调度——有没有一种理智的方法可以在没有 O(n^2) 代码的情况下做到这一点?
我有以下。有用。我想以一种避免使用动态的方式来做到这一点,并避免让代码在类型数量上增长为 O(n^2)。我知道的标准双分派解决方案在 A、B、C、D 类型的每个类型中都有 O(n) 代码,导致总体 O(n^2)。
有没有理智的方法可以做到这一点?
输出是:
有关背景,请参阅有关双重调度的替代方案的这个问题。
c++ - 消息系统的观察者模式+访问者模式
最近我开始实现一个使用“观察者模式”的消息调度系统:这里没什么特别的。当我开发它时,我认为从“主题”发送“消息”对象会很好,这些对象可能彼此根本不同,并且可以从许多“观察者”那里读取。
这些不同的消息采取不同消息类别的形式(例如,想想“用户注销消息”、“屏幕模式切换”和“音量级别已更改”,所有这些都需要不同的信息),很快我发现“观察者" 不需要知道我想要创建的每条不同的信息(至少可以说,这将是……不可持续的)。相反,我希望每个观察者都能够对特定类型的消息做出反应。
因此,为了制作一些东西,我认为双重调度可能是我的选择。经过一点点我得到了这篇文章(c ++ 11只是因为for循环):
为了清楚起见,我将在这里说出我的目标:
- 能够从主题发送许多不同的消息。
- 让观察者专门化他们忽略不适合他们的每条消息(如果根本不发送它们会更好,但我知道我可以注册不同的观察者组)。
- 避免 RTTI 和派生类转换。
我的问题来了:我是否错过了一个更简单的实现来实现我的目标?
值得一提的是,将使用此系统的系统不会有那么多观察者,可能同时出现的对象可能少于十个。
java - Java中的多态非curried方法调用(即席多态)
让我从一个例子开始。
假设我有一个抽象Vehicle
类。
而类Car
和Bicycle
继承自这个抽象类。
当我将该ride()
方法应用于Vehicle
实际类型只能在运行时确定的类型对象时,JVM 将应用正确版本的ride()
.
也就是说,在 sort 的柯里化方法调用中v.ride()
,多态以预期的方式工作。
但是,如果我有一个只接受一个子类型Vehicle
作为参数的方法形式的外部实现呢?那么,如果我有repair(Bicycle b)
和repair(Car c)
方法呢?uncurried 多态方法调用repair(v)
将不起作用。
例子:
我必须检查班级名称和沮丧。有没有更好的解决方案?
编辑:我的实际目的是我正在遍历一个抽象语法树,我碰巧注意到我想要双重调度。
Ast
是一个抽象类,实际的 AST 节点(如Assign
、MethodCall
或)从中ReturnStmt
继承。body
是Ast
s 的多态列表。
代码片段:
我实现双重调度的唯一可能性是检查类和向下转换或正确实现访问者模式,对吗?
java - 双重调度和继承
我有许多愚蠢的对象类,我想将它们序列化为字符串,以用于进程外存储。这是一个非常典型的使用双重调度/访问者模式的地方。
使用此模型,保存数据的类不需要知道序列化该数据的可能方法。JSON 是一种选择,但另一个序列化程序可能会将数据类“序列化”为 SQL 插入语句。
如果我们看一下其中一个数据类的实现,它的实现看起来与所有其他类几乎相同。类调用传递给它的serialize()
方法,提供自己作为参数。Serializer
我理解为什么不能将这个通用代码拉入父类。尽管代码是共享的,但编译器清楚地知道在该方法中的类型this
是ExtFileSystemIdentifier
并且可以(在编译时)写出字节码以调用serialize()
.
我相信我也了解 V 表查找时发生的大部分情况。编译器只知道serializer
参数是抽象类型Serializer
。它必须在运行时查看serializer
对象的 V 表以发现serialize()
特定子类的方法的位置,在这种情况下JsonSerializer.serialize()
典型的用法是获取一个已知为的数据对象,Serializable
并通过将其提供给一个已知为Serializer
. 对象的具体类型在编译时是未知的。
此实例的工作方式与其他调用类似,但相反。
V 表查找现在在 的实例上完成,Serializable
它将找到,例如ExtFileSystemIdentifier.serialize
. 它可以静态地确定最接近的匹配重载是 for Serializer<T>
(它恰好也是唯一的重载)。
这一切都很好。它实现了保持输入和输出数据类忽略序列化类的主要目标。它还实现了第二个目标,即为序列化类的用户提供一致的 API,而不管正在执行哪种序列化。
现在想象一下,另一个项目中存在第二组哑数据类。需要为这些对象编写一个新的序列化程序。现有Serializable
接口可以在这个新项目中使用。Serializer
但是,该接口包含对来自其他项目的数据类的引用。
为了概括这一点,Serializer
接口可以分为三个
这样,Serializer
和Serializable
接口可以被打包和重用。但是,这会破坏双重调度,并导致代码中的无限循环。这是我在 V 表查找中不确定的部分。
在调试器中单步执行代码时,在数据类的serialize
方法中会出现问题。
我认为正在发生的是,在编译时,编译器正试图serialize
从接口中的可用选项中为方法选择正确的重载Serializer
(因为编译器只知道它是 a Serializer<T>
)。这意味着当我们到达运行时进行 V 表查找时,正在寻找的方法是错误的,运行时将选择JsonSerializer.serialize(Serializable)
,导致无限循环。
这个问题的一个可能的解决方案是serialize
在数据类中提供一个更特定于类型的方法。
程序控制流将反弹,直到达到最特定类型的Serializer
重载。届时,该ProjectASerializer<T>
接口将为来自项目 A 的数据类提供更具体serialize
的方法;避免无限循环。
这使得双重调度稍微不那么有吸引力。数据类中现在有更多样板代码。显然重复的代码不能被分解到父类中,这已经够糟糕的了,因为它规避了双重分派的诡计。现在,它更多了,而且它与序列化器的继承深度相结合。
双重调度是静态类型的诡计。是否有更多静态类型技巧可以帮助我避免重复代码?
c++ - C++ 类型比较:typeid vs double dispatch dynamic_cast
是否有任何性能或稳健性的理由偏爱其中一种?
输出: