设计模式学习笔记十二:访问者模式

对比Java设计模式编程中的状态模式和策略模式 主要介绍了Java设计模式编程中的状态模式和策略模式对比,文中列举了两种模式的相似点和不同点,并都举了代码的实例作为参照,需要的朋友可以参考下 立即下载

设计模式学习笔记十二:访问者模式

介绍

访问者(visitor)模式,属于对象行为型模式,它实现了结构与行为的解耦。
意图:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。(本段摘自《GoF设计模式》 5.11)

适用场景

访问者模式适合对象的结构稳定,行为变动频繁的情况。反之,结构变动频繁的场景不适合使用次模式。在后面的实现中可以很容易的证实这一点,结构的变化会增加更多繁复的操作。在一个已经的接口中增加方法会导致在其所有的实现类中都进行一次实现实现,没人愿意这么做。

UML结构图:

可以先略过,回头再看。
Visitor

场景模拟

这里我以客户回访场景尝试解释访问者模式的应用:在公司Z中,会定期对他的客户进行回访。根据客户重要度的不同,人物、时间、地点也会不同。不管是否愿意承认,生活中到处充满着等级的划分不是么?
+ 普通客户:铜牌业务员A;时间:工作日;地点:电话连线。
+ 潜力优质客户:银牌业务员B;时间:沟通确定;地点:茶楼。
+ 优质客户:金牌业务员C;时间:沟通确定;地点:避暑山庄。

代码实现:

1.回访操作

package com.array7.visitor;

/**
 * 回访接口,即Element
 */
public interface IRevisit {
    void accpet(IWorkerVisitor visitor);
}

/**
 * 约定的业务员,即ConcreteElement
 */
public class Worker implements IRevisit {

    @Override
    public void accpet(IWorkerVisitor visitor) {
        visitor.visit(this);
    }
}

/**
 * 约定的回访时间,即ConcreteElement
 */
public class Time implements IRevisit {
    @Override
    public void accpet(IWorkerVisitor visitor) {
        visitor.visit(this);
    }
}

/**
 * 约定的地点,即ConcreteElement
 */
public class Place implements IRevisit {
    @Override
    public void accpet(IWorkerVisitor visitor) {
        visitor.visit(this);
    }
}

/**
 * 最终回访单,即ConcreteElement
 */
public class Revisit implements IRevisit {
    private IRevisit[] revisits;
    public Revisit(IRevisit... revisits) {
        this.revisits = revisits;
    }
    @Override
    public void accpet(IWorkerVisitor visitor) {
        for (IRevisit revisit : revisits) {
            revisit.accpet(visitor);
        }
        visitor.visit(this);
    }
}

2.访问者操作

package com.array7.visitor;

/**
 * 访问者接口,即Visitor
 */
public interface IWorkerVisitor {
    void visit(Worker worker);
    void visit(Time time);
    void visit(Place place);
    void visit(Revisit revisit);
}

/**
 * 金牌业务员访问者,即concreteVisitor
 */
public class CustomerAVisitor implements IWorkerVisitor {
    @Override
    public void visit(Worker worker) {
        System.out.println("安排金牌业务员A回访客户");
    }

    @Override
    public void visit(Time time) {
        System.out.println("安排金牌业务员A与客户约定时间:2015-07-26");
    }

    @Override
    public void visit(Place place) {
        System.out.println("安排金牌业务员A与客户约定地点:避暑山庄");
    }

    @Override
    public void visit(Revisit revisit) {
        System.out.println("金牌业务员A开始回访");;
    }
}

/**
 * 银牌业务员访问者,即concreteVisitor
 */
public class CustomerBVisitor implements IWorkerVisitor {
    @Override
    public void visit(Worker worker) {
        System.out.println("安排银牌业务员B回访客户");
    }

    @Override
    public void visit(Time time) {
        System.out.println("安排银牌业务员B与客户约定时间:2015-07-26");
    }

    @Override
    public void visit(Place place) {
        System.out.println("安排银牌业务员B与客户约定地点:茶楼");
    }

    @Override
    public void visit(Revisit revisit) {
        System.out.println("银牌业务员B开始回访");
    }
}

/**
 * 铜牌业务员访问者,即concreteVisitor
 */
public class CustomerCVisitor implements IWorkerVisitor {
    @Override
    public void visit(Worker worker) {
        System.out.println("安排铜牌业务员C回访客户");
    }

    @Override
    public void visit(Time time) {
        System.out.println("铜牌业务员C不需要与客户约定时间");
    }

    @Override
    public void visit(Place place) {
        System.out.println("铜牌业务员C不需要与客户约定地点");
    }

    @Override
    public void visit(Revisit revisit) {
        System.out.println("铜牌业务员C开始回访");
    }
}

3.Run

public class Run {
    public static void main(String[] args) {
        IRevisit revisitA = new Revisit(new Worker(), new Time(), new Place());
        revisitA.accpet(new CustomerAVisitor());
        System.out.println();
        IRevisit revisitB = new Revisit(new Worker(), new Time(), new Place());
        revisitB.accpet(new CustomerBVisitor());
        System.out.println();
        IRevisit revisitC = new Revisit(new Worker(), new Time(), new Place());
        revisitC.accpet(new CustomerCVisitor());
    }
}

输出

安排金牌业务员A回访客户
安排金牌业务员A与客户约定时间:2015-07-26
安排金牌业务员A与客户约定地点:避暑山庄
金牌业务员A开始回访

安排银牌业务员B回访客户
安排银牌业务员B与客户约定时间:2015-07-26
安排银牌业务员B与客户约定地点:茶楼
银牌业务员B开始回访

安排铜牌业务员C回访客户
铜牌业务员C不需要与客户约定时间
铜牌业务员C不需要与客户约定地点
铜牌业务员C开始回访

策略模式与访问者模式的区别

之前有讲过策略设计模式(http://blog.youkuaiyun.com/array7/article/details/43833921),仔细考虑发现本文中的场景适用策略模式也同样可以实现,并且会比适用访问者模式更加简单。下面来对两者进行一下比较:
+ 两者都属于对象行为型模式,同时都体现了对算法的封装,并且都可以在运行时动态指定算法。
+ 区别体现在策略模式只有一个上下文,策略模式的结构决定了Context只能传递一个策略进入。访问者模式则可以是在实现化Element结构之后,随时可以指定多个访问者。虽然在场景模拟中没有特意做区分,但是通过代码的实现的我们发现是可以很容易做到的。
+ 如果策略模式的算法部分不放在构造对象中传入,而使用accpet方法传入,那么这个策略模式就是一个访问者模式的实现了。So,策略模式也可以看成是访问者模式的一个特例。就像工厂方法模式是抽象工厂模式的一个特例一样。

总结

从上面的实现来看引证了适用场景中说的访问者模式适合对象的结构稳定,行为变动频繁的情况。反之,结构变动频繁的场景不适合使用次模式。
+ 在结构不变的情况,增加行为即增加访问者是很容易的,只要新政一个访问者的实现即可。
+ 如果更改了结构(如Element的增删改),访问者接口要发生变动,同时所有访问者实现都要对应调整。

以上是我理解的访问者模式,了解优劣才知何时适用。
不准确之处还请指正,十分感谢!

基于 parallels ubuntu 20.04 LTS (focal) 的ros+px4+gazebo 安装 基于 parallels ubuntu 20.04 LTS (focal) 的ros+px4+gazebo 安装。 阅读详情

相关推荐

借助OSS搭建在线教育视频课程分享网站-阿里云的课程体验和记录

阿里云的《搭建在线教育网站》免费课程里面讲的啥,我点进去看了看

LegendNoTitle的博客 3023

设计模式问答(三)

状态模式、策略模式、访问者模式、适配器模式、享元模式详解

程序员学架构的博客 857

AS5600磁编码器选型与安装避坑指南:磁铁形状、间隙距离到底怎么选?(附实测数据)

本文详细解析了AS5600磁编码器的选型与安装要点,包括磁铁形状、间隙距离等关键参数的选择,并附有实测数据支持。特别针对Arduino和I2C接口的应用场景,提供了硬件选型和机械安装的实用指南,帮助开发者避免常见陷阱,提升系统精度和稳定性。

weixin_27038245的博客 290

【再探】设计模式—访问者模式、策略模式及状态模式

访问者模式是用于访问复杂数据结构的元素,对不同的元素执行不同的操作。策略模式是对于具有多种实现的算法,在运行过程中可动态选择使用哪种具体的实现。状态模式是用于具有不同状态的对象,状态之间可以转换,且不同状态下对象的行为不同,客户端可以不必考虑其状态及转换,对所有的状态都可以执行同一的操作。

KEEP CODING 1540

别再手动拷贝文件了!用Keil MDK的Pack Installer一键搞定STM32上的RT-Thread Nano移植

本文详细介绍了如何使用Keil MDK的Pack Installer一键快速移植RT-Thread Nano到STM32项目,告别繁琐的手动拷贝和配置过程。通过自动化版本管理和依赖处理,移植时间从47分钟缩短至3分钟,大幅提升开发效率。文章还提供了实战步骤、高级配置技巧和常见问题解决方案,帮助开发者轻松实现RTOS集成。

weixin_29194817的博客 365

55、宇宙微波背景辐射望远镜及其光学系统解析

本文详细解析了宇宙微波背景辐射(CMB)望远镜及其光学系统的设计与优化。内容涵盖折射与反射光学系统的特性、旁瓣控制技术、气球与地面观测系统的对比、探测器阵列的发展、光学系统设计流程以及不同观测场景下的光学系统选择。同时,文章展望了CMB望远镜光学系统的未来发展趋势,包括技术创新、多频段观测、国际合作与大型项目等。通过系统性的分析与对比,为CMB研究提供了全面的技术支持与理论基础。

f9g0h的博客 145

访问者模式(Visitor)

定义: 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 本质: 将数据和作用于数据上的某种/些特定操作分离开来。 为ADT预留一个将来可扩展功能的“接入点”,外部实现的功能代码可以在不改变ADT本身的情况下通过delegation接入ADT。 举例说明: /* Abstract element interface (visitable)...

logictime2的博客 652

git clone出现fatal: unable to access Failed to connect to github.com port 443: Timed out解决方案

本文主要介绍了git clone出现fatal: unable to access Failed to connect to github.com port 443: Timed out解决方案,希望能对使用git的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 23万+

通俗讲解visitor访问者模式及其与策略模式的比较-设计模式-表现型

电脑装机的场景学习访问者模式,并比较学习策略模式。

phs999的博客 1514

【ROS2】RViz2加载URDF模型文件

1)运行RViz2rviz22)添加组件:RobotModel3)选择通过文件添加4)选择URDF文件,此时会报错,需要修改Fixed Frame为map即可

郭老二 1451

级联H桥构网型储能SVG系统设计与VSG控制策略研究

随着新能源渗透率不断提高,电力系统惯量和阻尼水平持续下降,传统跟网型控制策略在弱电网条件下的稳定性面临严峻挑战。构网型控制以电压源方式运行,能够为系统提供惯量和频率支撑,成为当前研究热点。本文针对10kV/10Mvar级联H桥构网型储能静止无功发生器(SVG),采用星形连接拓扑结构,设计了基于虚拟同步发电机(VSG)的构网型控制策略。文章从主电路拓扑设计、数学建模、VSG控制策略设计、调制策略、直流电压平衡控制、系统参数设计、仿真建模和硬件实现等八个方面展开系统论述,给出了完整的Simulink仿真模型~~

huanghm88的专栏 356

设计模式学习笔记(二十二)访问者模式

1、增加新的操作:通过引入访问者模式,可以在不修改已有元素类的情况下,定义新的操作。这样可以增加系统的灵活性和可扩展性。2、分离数据结构和操作:访问者模式将数据结构和对数据的操作分离开来,使得操作可以独立于数据结构进行变化。3、符合开闭原则:当需要新增一种操作时,只需增加一个新的具体访问者类,而无需修改已有元素类和其他访问者类。1、增加新的元素类困难:在访问者模式中,每增加一个新的元素类,都需要在访问者接口和所有的具体访问者类中增加相应的访问方法,这可能导致类的层次结构变得复杂。

weixin_44917291的博客 270

【华为OD机试真题】390、AI面板识别 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)

题目描述 >AI识别到面板上有N(1 ≤ N ≤ 100)个指示灯,灯大小一样,任意两个之间无重叠。   由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2,y2),   请输出先行后列排序的指示灯的编号,排序规则:   1、每次在尚未排序的灯中挑选最高的灯作为的基准灯   2、找出和基准灯属于同一行所有的灯进行排序。两个灯高低偏差不超过灯半径算同一行(即两个灯坐标的差 ≤ 灯高度的一半)

KJ.JK 1805

步步为营 .NET 设计模式学习笔记系列总结

设计模式我从开篇到23种设计模式的讲解总共花了进两个月的时间,其间有很多读者给我提出了很好的建议,同时也指出了我的不足,对此我表示感谢,正是由于很多读者的支持我才能坚持的写到最后.在此表示我真诚的谢意. 系列导航 步步为营 .NET 设计模式学习笔记 一、开篇(设计模式之泡妞二十三招) 步步为营 .NET 设计模式学习笔记 二、Abstract Factory(抽象工厂) 步...

weixin_34277853的博客 233

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

图解Java设计模式学习笔记——行为型模式(模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式)

一、模板方法模式(模板模式)——钩子方法 二、命令模式(源码讲解) 三、访问者模式-双分派 四、迭代器模式(iterator) 五、观察者模式(Observer) 六、中介者模式(Mediator Pattern) 七、备忘录模式(Memento Pattern) 八、解释器模式(Interpreter Pattern) 九、状态模式(State Pattern) 十、策略模式(Strategy Pattern) 十一、责任链模式(职责链模式)(Chain of Responsibili

chenjian723122704的专栏 522

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

java23种设计模式个人整理_GoF设计模式合集

1 概述 这篇文章是对GoF23种设计模式+1种非GoF模式的合集,由笔者自己的笔记整理而来,每个模式都详细描述了步骤,角色等,以及使用Java实现的具体的例子,下面是目录:基础设计模式概述UML基础创建型模式单例模式简单工厂模式(非GoF模式)工厂方法模式抽象工厂模式原型模式建造者模式结构型模式适配器模式桥接模式组合模式装饰模式外观模式享元模式代理模式行为型模式职责链模式命令模式解释器模式迭代器...

weixin_39669133的博客 105

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

设计模式学习笔记(目录篇)

设计模式学习笔记(目录篇) 为了方便查看,特此将设计模式学习笔记系列单独做一个目录。   1   设计模式学习笔记(一:命令模式) 2   设计模式学习笔记(二:观察者模式) 3   设计模式学习笔记(三:装饰模式) 4   设计模式学习笔记(四:策略模式) 5   设计模式学习笔记(五:适配器模式) 6   设计模式学习笔记(六:责任链模式) 7   设计模式学习笔记(七:外观...

weixin_34183910的博客 133

Java设计模式学习笔记 --- 万字总结归纳

本书是一本关于设计模式的实用指南。设计模式是面向对象编程的基石,它们为解决常见的软件设计问题提供了经验丰富的解决方案。通过深入浅出的示例和清晰的代码,本书引导读者掌握工厂模式、单例模式、观察者模式、策略模式等关键设计模式。 每个模式都经过仔细解释,包括问题、解决方案、示例代码和类图。这有助于读者理解模式的核心思想,并学会在实际项目中应用它们。无论您是初学者还是经验丰富的开发者,本书都将成为您的设计模式宝典,提高软件的可维护性和可扩展性。

qq_45786626的博客 712

设计模式学习笔记(二十二)—FlyWeight享元模式

转贴自 http://www.blogjava.net/flustar/archive/2007/12/15/visitor.htmlVisitor模式定义:表示一个作用于某对象结构中各元素的操作。它可以使你不修改各元素类的前提下定义作用于这些元素的新操作,也就是动态的增加新的方法。Visitor模式结构图: Visitor模式中主要角色:1) 访问者角色(Visitor):为

icecityman的专栏 397

设计模式个人学习笔记

(一)策略模式策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略

新博客地址http://www.cnblogs.com/millionsmultiplication/ 583

【Java封神之路】设计模式学习-第一天

我为什么选择学习设计模式 从学校毕业已有四年时间,面对长期的CRUD,整个人的学习活力已经大不如前,越来越疲倦,面对自己的职业人生以及我们的行业特性让我们必须要有一颗不断进步不断学习的品质,于是我便决定回到起点,重新出发,从最基本的,最贴近日常开发的设计模式开始,重启我的学习之路,我的一切动力来源自己的成长和与大家的分享,不计章节,开设免费专栏,深入浅出的来表述自己的学习心得,记录学习过程。 本专栏与大家的约定 专栏约定与各位每周日早上10点更新本周最新学习笔记,包含本周所学全部内容,无保留的全部与大家分享

杨鹏的博客 236

设计模式学习笔记(C++实现)(二十三)--模板方法模式

1.模板方法模式简介 英文名称 Template Method 主要目的 该模式定义一个操作中的算法的基本框架,而将一些步骤延迟到子类中进行。模板方法模式可以使得子类在不改变算法框架的情况下,重定义该算法的某些特定步骤。 使用场景 1.一次性实现一个算法不变的部分,并将可变的部分留给子类来实现; 2.各个子类的公共行为被提取出来并集中到一个公共父类中进行,从而减少代码重复; 3.控制...

以文会友 389
上一篇: 设计模式学习笔记十一:观察者模式
下一篇: 设计模式学习笔记十三:模板方法模式
七郎
博客等级 码龄14年 31粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值