引言

说实话,我看过GoF《Design Patterns》,也曾深深的被李建忠《设计模式》系列Webcast吸引。但是还没有见过“Double Dispatch模式”。的确GoF提及的设计模式只是最初对设计模式的系统介绍,它不可能涵盖所有的模式。另外随着时间的流逝,技术日新月异的变化,技术大牛们又总结出了许多新的模式。

今天所介绍的Double Dispatch模式,从时间上来看,已不是新的设计模式;但对于只看过GoF设计模式的技术同仁来说,也算是一个新的设计模式。

什么是DoubleDispatch?

对,没有“模式”二字。从字面翻译来看,网上好多人翻译为双分发,双分派。Wiki上对Double Dispatch的解释:

大意:

在软件工程中,Double Dispatch是一种特殊形式的Multiple Dispatch,也是根据于两个对象的运行时类型来调用的其相应具体类(不是基类)方法的一种机制。在大多数面向对象的系统中,在代码(程序)中的一个函数调用具体类的方法都取决于单个对象的动态类型(运行时的类型),(它们一般)被称为Single Dispath calls,或只是虚拟函数调用。

不难看出一次虚函数的调用叫做Single Dispath ,那么Double Dispatch应该就是两次虚函数的调用啦。

更进一步说就是一次通过动态类型(运行时类型)调用相应子类真实类型的方法函数,就称为一次Dispath。那么以此类推,需要两次通过运行时类型调用相应类型的方法函数,则称为Double Dispatch。

举例说明:

Single Dispatch 实例:

Double Dispatch讲解与实例-面试题-LMLPHP

DoubDispatch 实例:

为啥要搞Double Dispatch?

Double Dispatch讲解与实例-面试题-LMLPHP

Double Dispatch讲解与实例-面试题-LMLPHP

Double Dispatch讲解与实例-面试题-LMLPHP

输出结果

Double Dispatch讲解与实例-面试题-LMLPHP

怎么没有输出“Dog Type”和“Mammals Type”呢?不对呀!!

怎么解决?

用Dynamic来解决

通过查阅关于函数重载决议相关的说明我们可以了解到:

Double Dispatch讲解与实例-面试题-LMLPHP

输出结果:

Double Dispatch讲解与实例-面试题-LMLPHP

这样的解决虽然看起来解决了问题?但我不通过Double Dispatch 来实现的。只是通过了Dynamic。

用Vistor 模式来解决

Double Dispatch讲解与实例-面试题-LMLPHP

总结

C# 现在引入Dynamic 来支持“Double Dispatch”,但我们应该清楚到底为什么要用这个关键字.

如果没有这个关键字,C#又是如何支持“Dobule Dispatch”的,这就是本篇所讲的目的。

更多关于Vistor内容,大家可自行百度谷歌。

后续我想写一篇关于Vistor的博客,还请大家多多支持!

参考

设计模式随笔-让众口不再难调

Software design pattern

GoF著作中未提到的设计模式(4):Double Dispatch

关于双分派(Double Dispatch)的一点探讨(案例讲的很透彻,C++的代码)

完成C++不能做到的事 - Visitor模式

Double dispatch in C#?

Dynamic Dispatch in C#

Acyclic Visitor模式:http://www.objectmentor.com/resources/articles/acv.pdf

Hierachical Visitor Pattern模式:http://en.wikipedia.org/wiki/Hierarchical_visitor_pattern

05-11 08:49