`

让我最后罗嗦一下Visitor模式——关于双重分派

阅读更多

        昨天罗嗦了一下Visitor模式idior以及Cavingdeep兄都写下了很多促使我进一步去思考的Feedback,在这里谢谢两位了!感谢的话说完了,让我们言归正传——开始罗嗦,呵呵。
        在昨天的Post中我提到了Visitor模式中最重要的一点是:double-dispatch(双重分派)。说来惭愧,昨天在写post的时候,我仅仅在震宇兄的Post中对double-dispatch有了概念上的理解,并且认为accept方法是为了实现double-dispatch的。然而idior和Cavingdeep兄的问题让我心里没了谱:accept为什么要存在,为什么不直接visit呢?早上在看了Cavingdeep兄的Post之后,我想要解决这个问题,得从到底什么是双重分派入手了。于是google了一番,终于有点开窍了。
        在说双重分派以前,我们先来看看以下代码[1]

SuperClass a = new SubA();
SuperClass parameter 
= new SubB();
a.commonMethod(parameter);

我们都知道由于动态类型绑定,尽管a声明为SuperClass类型,但a.commonMethod调用的是SubA中override的commonMethod,这就是多态的一种体现。如果在SubA类中有这样的重载方法:

commonMethod(SuperClass arg)  }
commonMethod(SubA arg) 
 }
commonMethod(SubB arg) 
 }

那么a.commonMethod调用的又是哪个方法呢?你的心里有非常肯定的答案吗?写段代码尝试一下,你会发现第一个commonMethod被调用了。这里就引出了一个问题:动态类型绑定只会体现在方法的调用者身上,而方法的参数类型则会在编译期由编译器决定
        如果参数类型也能够在运行期决定,那么哪个commonMethod被调用就由方法调用者和方法参数共同在运行期决定了。那么如何实现参数类型在运行期绑定呢?既然方法调用者的类型是运行期才确定的,那么我们就可以反客为主了,将方法参数变成方法调用者。

commonMethod(SuperClass arg) {
    arg.commonMethod(
this);
}

至此,您应该明白双重分派的涵义了吧?哪个commonMethod最终被调用经过两次运行期类型绑定才确定下来,这样的过程就是双重分派了。由此延伸开来,多重分派也就不难理解了。
        在双重分派当中,还有一个关键细节,您是否发现了呢?那就是您所期待的SubA中的CommonMethod(SubB arg)方法被调用的情况并没有出现,反而是SubB中的CommonMethod(SubA arg)的方法被调用了。不管怎么样,双重分派给程序带来了更多的灵活性。        
        说完了双重分派,我们再回到Visitor模式上来。Visitor模式其实就是将以上所说的commonMethod从数据对象中抽离出来封装至单独的类中,那么为了维持原有的双重分派,accept方法就派上了用场。没有了accept,就无法在数据操作从数据对象中分离出来的同时保持双重分派。同时,您也会发现commonMethod有一个非常大的特点:它是一个跨对象操作的方法。对应到Visitor模式里众多的Visitor类,重载的visit方法正好体现了跨对象操作的特点。
       
        也许我讲述的还不是很清楚,有兴趣的朋友可以参考以下这篇给我带来很大启发的文章。
         
        [1] Double Dispatch Mechanism

分享到:
评论

相关推荐

    设计模式C++学习之访问者模式(Visitor)

    访问者模式(Visitor)是一种行为设计模式,它允许在不修改对象结构的前提下向对象结构中的元素添加新的操作。这种模式将算法与数据结构分离,使得算法可以独立于数据结构进行变化,增强了系统的可扩展性。 在C++中...

    C#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式

    在本篇文章中,我们将深入探讨面向对象设计模式中的一个非常重要的模式——**Visitor(访问者)模式**。此模式属于行为型模式的一种,主要应用于在不修改现有类的情况下向其添加新功能。这对于保持代码的灵活性和可...

    C++ Visitor模式

    **C++ Visitor模式详解** Visitor模式是设计模式中的一种行为模式,它在对象结构中引入了一个访问者角色,使得访问者能够对结构中的每个元素进行操作,而不改变元素本身的行为。这种模式允许我们在不修改已有类的...

    基于visitor模式和访问者模式的表达式树_求值引擎

    本项目基于“visitor模式”和“访问者模式”,实现了用于计算表达式的求值引擎,这涉及到一种将数学表达式转化为数据结构(表达式树)的方法,然后通过遍历该树来执行计算。下面我们将详细探讨这些概念。 1. **...

    设计模式之访问者模式(Visitor)

    **访问者模式(Visitor)详解** 访问者模式是一种行为设计模式,它使你可以在不修改对象结构的情况下,为对象添加新的操作。这种模式的核心在于将数据结构与对这些数据的操作解耦,使得增加新的操作变得容易,同时...

    Visitor模式

    访问者模式(Visitor Pattern)是一种行为设计模式,它使你能在不修改对象结构的前提下,为对象添加新的操作。这种模式在处理具有复杂逻辑和多种类型的对象结构时特别有用,因为它允许你在不改变原有结构的情况下,...

    试试visitor设计模式

    也许最开始出现这种模式,是因为另外的原因: 我有一堆数据放在一个库里头,不想让其它人拿着, 如果你要用数据干活,那你就把函数指针给我,我来替你使用这个数据。...然后人们就说,这是visitor模式。

    设计模式-Java语言中的应用(pdf)

    《设计模式——Java语言中的应用》是一本专为Java开发者深入理解面向对象设计而编写的经典书籍。设计模式是软件工程领域中经过实践验证的、解决常见问题的有效方案,它们代表了在特定上下文中,针对特定问题的最优...

    设计模式系列之visitor

    "设计模式系列之visitor"是一个关于软件设计模式的讨论,特别是关注于“访问者”(Visitor)模式。这个模式是GOF(Gamma, Helm, Johnson, Vlissides)在他们的经典著作《设计模式:可复用面向对象软件的基础》中提出...

    设计模式代码——c#

    C#设计模式(23种设计模式) 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3. 建造者模式(Builder) 4. 工厂方法模式...22. 访问者模式(Visitor Pattern) 23. 状态模式(State Pattern)

    设计模式精解——GoF23中设计模式解析

    ### 设计模式精解——GoF23中设计模式解析 #### 重要性与起源 设计模式是软件工程领域的一项重要研究,它提供了一系列解决常见软件设计问题的模板。GoF23指的是由Erich Gamma、Richard Helm、Ralph Johnson和John ...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    设计模式可复用面向对象软件的基础.zip

    书名: 设计模式可复用面向对象软件的基础 英文原书名: Design Patterns:Elements of Reusable Object-Oriented software 作者: Erich Gamma 等 译者: 李英军 马晓星 蔡敏 刘建中 书号: 7-111-07575-7 页码: 254 定价...

    访问者模式VisitorPattern

    **访问者模式(VisitorPattern)** 访问者模式是一种行为设计模式,它使你能在不修改对象结构的前提下向对象添加新的操作。这种模式常用于处理具有复杂逻辑的对象结构,特别是当你需要对这些对象进行多态操作时。访问...

    Java 的双重分发与 Visitor 模式实例详解

    Java 的双重分发与 Visitor 模式实例详解 Java 中的双重分发(Double Dispatch)是一种机制,允许在运行时确定方法的调用,而不仅仅是根据方法的接收者,还受参数类型的决定。这种机制可以实现面向对象的多态。 在...

    C#设计模式之Visitor

    **C#设计模式之Visitor** **一、设计模式概述** 设计模式是软件开发中的经验总结,它提供了解决常见问题的可复用解决方案。在C#编程中,设计模式可以帮助我们编写更灵活、可扩展和易于维护的代码。"Visitor"(访问...

    23种 设计模式---面向对象的基本原则

    - 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 这些设计模式不仅在PHP中适用,也是跨语言的编程思想,可以帮助开发者...

Global site tag (gtag.js) - Google Analytics