双分派是一种根据两个对象的运行时类型共同决定调用哪段代码的技术。它突破了大多数面向对象语言只按单个接收者类型分派的限制,常用来实现按两个操作数类型变化的行为,访问者模式即建立在它之上。

| 中文名 | 双分派 |
| 外文名 | Double Dispatch |
| 类别 | 多态技术 |
| 相关模式 | 访问者模式 |
| 分派维度 | 两个运行时类型 |
双分派(Double Dispatch)是指方法的实际执行逻辑由两个对象的运行时类型共同决定的一种技术。它区别于常规面向对象语言中仅依据单个接收者(this)类型选择方法的单分派机制。
大多数主流语言如 Java、C++、C# 只支持单分派:调用一个虚方法时,运行时只根据调用对象自身的实际类型来选择重写版本,而方法参数只按其声明类型静态绑定。当某个行为需要随两个参与对象的类型组合而变化时,单分派就不够用了。双分派通过两次连续的虚方法调用,让两个对象的实际类型依次参与决策,从而模拟出按两个类型联合分派的效果。
双分派的经典做法是让第一个对象调用第二个对象的方法,并把自身作为参数传回,由此触发第二次虚调用:
访问者模式正是双分派的工程化封装:元素的 accept 方法完成第一次分派,访问者的 visit 重载完成第二次分派。
双分派适用于行为依赖两个类型组合的场合,例如游戏中不同类型物体之间的碰撞处理(飞船撞小行星与飞船撞飞船逻辑不同)、编译器对不同节点与不同操作的组合、图形系统中不同图元与不同渲染器的配对、以及需要为已有类层次追加操作而不改动原类的访问者结构。
问:双分派和方法重载有什么区别?答:重载是编译期按参数静态类型选择的,属于静态绑定;双分派通过两次虚调用把参数的动态类型也纳入决策,是运行期行为。
问:能否直接用类型判断代替双分派?答:可以用一连串 if instanceof 判断实现相同效果,但会产生大量条件分支,难以扩展和维护,双分派用多态取代了这些分支。

| 中文名 | 双分派 |
| 外文名 | Double Dispatch |
| 类别 | 多态技术 |
| 相关模式 | 访问者模式 |
| 分派维度 | 两个运行时类型 |
登录 后参与讨论
暂无讨论,来发表第一条评论吧