访问者模式
概念
访问者模式:允许一个或者多个操作应用到一组对象上,解耦操作和对象本身。
使用场景
一般来说,访问者模式针对的是一组类型不同的对象(PdfFile、PPTFile、WordFile)。不 过,尽管这组对象的类型是不同的,但是,它们继承相同的父类(ResourceFile)或者实 现相同的接口。在不同的应用场景下,我们需要对这组对象进行一系列不相关的业务操作 (抽取文本、压缩等),但为了避免不断添加功能导致类(PdfFile、PPTFile、WordFile) 不断膨胀,职责越来越不单一,以及避免频繁地添加功能导致的频繁代码修改,我们使用访问者模式,将对象与操作解耦,将这些业务操作抽离出来,定义在独立细分的访问者类 (Extractor、Compressor)中。
为什么支持双分派的语言不需要访问者模式?
Single Dispatch,
指的是执行哪个对象的方法,根据对象的运行时类型来决定;执行对象的哪个方法,根据方法参数的编译时类型来决定。
Double Dispatch
指的是执行哪个对象的方法,根据对象的运行时类型来决定;执行对象的哪个方法,根据方法参数的运行时类型来决定。
Single 和 Double
Single Dispatch 之所以称为“Single”,是因为执行哪个对象的哪个方法,只跟“对象”的运行时类型有关。Double Dispatch 之所以称为“Double”,是因为执行哪个对象的哪个方法,跟“对象”和“方法参数”两者的运行时类型有关。
Java的Single Dispatch
Java 支持多态特性,代码可以在运行时获得对象的实际类型(也就是前面提到的运行时类 型),然后根据实际类型决定调用哪个方法。尽管 Java 支持函数重载,但 Java 设计的函数重载的语法规则是,并不是在运行时,根据传递进函数的参数的实际类型,来决定调用哪个重载函数,而是在编译时,根据传递进函数的参数的声明类型(也就是前面提到的编译时 类型),来决定调用哪个重载函数。也就是说,具体执行哪个对象的哪个方法,只跟对象的运行时类型有关,跟参数的运行时类型无关。所以,Java 语言只支持 Single Dispatch。
demo
1 | public class ParentClass { |
注:Java作为Single Dispatch,执行重载方法的时候,只会根据执行方法时传递的参数声明时的类型来执行,并不会关注他到底实例化了哪一个对象。
参考
《设计模式之美》