【设计模式】我终于读懂了访问者模式。。。

2023-05-16

🌰测评系统的需求

  1. 将观众分为男人和女人,对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价(评价 有不同的种类,比如 成功、失败 等)
  2. 传统方案
    在这里插入图片描述

🌱传统方式的问题分析

  1. 如果系统比较小,还是 ok 的,但是考虑系统增加越来越多新的功能时,对代码改动较大,违反了 ocp 原则, 不利于维护
  2. 扩展性不好,比如 增加了 新的人员类型,或者管理方法,都不好做
  3. 引出我们会使用新的设计模式 – 访问者模式

🌵访问者模式基本介绍

  1. 访问者模式(Visitor Pattern),封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

  2. 主要将数据结构与数据操作分离,解决 数据结构和操作耦合性问题

  3. 访问者模式的基本工作原理是:在被访问的类里面加一个对外提供接待访问者的接口

  4. 访问者模式主要应用场景是:需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联),同时
    需要避免让这些操作"污染"这些对象的类,可以选用访问者模式解决

🌴访问者模式的原理类图

在这里插入图片描述

🌲对原理类图的说明

  1. Visitor 是抽象访问者,为该对象结构中的 ConcreteElement 的每一个类声明一个 visit 操作
  2. ConcreteVisitor :是一个具体的访问值 实现每个有 Visitor 声明的操作,是每个操作实现的部分.
  3. ObjectStructure 能枚举它的元素, 可以提供一个高层的接口,用来允许访问者访问元素
  4. Element 定义一个 accept 方法,接收一个访问者对象
  5. ConcreteElement 为具体元素,实现了 accept 方法

🌳访问者模式应用实例

  1. 将人分为男人和女人,对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价(评价 有不同的种类,比如 成功、失败 等),请使用访问者模式来实现

  2. 思路分析和图解(类图)
    在这里插入图片描述

Action类

在这里插入图片描述

Success类

在这里插入图片描述

Fail类

在这里插入图片描述

person类,给一个接收action的方法

在这里插入图片描述

man类,将自己传入action的入参中

说明

  1. 这里我们使用到了双分派, 即首先在客户端程序中,将具体状态作为参数传递 Woman 中(第一次分派)
  2. 然后 man 类调用作为参数的 “具体方法” 中方法 getManResult, 同时将自己(this)作为参数
    传入,完成第二次的分派
    在这里插入图片描述

ObjectStructure类,数据结构,管理很多人(Man , Woman)

在这里插入图片描述

客户端类

在这里插入图片描述
在这里插入图片描述

🌻接下来我们debug进去看一下

通过添加方法,我们把男人和女人添加到数据结构类

在这里插入图片描述

进入display方法

在这里插入图片描述

循环调用person的方法

在这里插入图片描述

进入accept方法

在这里插入图片描述

进入了男人的accept方法中去

在这里插入图片描述

action实际是success,又调用自己(man)

在这里插入图片描述
在这里插入图片描述

失败亦是如此,如果我们新增一个转态wait,他仅仅要继承action类即可!

在这里插入图片描述

运行结果

在这里插入图片描述

🌺访问者模式在jdk源码中的应用

JDK的NIO中的 FileVisitor 接口采用的就是访问者模式。

在这里插入图片描述

walkFileTree方法,该方法就是对文件进行遍历操作

在这里插入图片描述

在这里插入图片描述

其中FileVisitResult是一个枚举类

在这里插入图片描述

他根据我们传入文件的path经过FileVisitor的方法得到对应的结果,然后做下一步的操作

在这里插入图片描述在这里插入图片描述

所以FileVisitor就类似于person,也就是Element 接收一个访问者对象

在这里插入图片描述

而我们传入的path(文件路径)就是我们的action,是抽象访问者

🍁应用案例的小结-双分派

上面提到了双分派,所谓双分派是指不管类怎么变化,我们都能找到期望的方法运行。双分派意味着得到执行的操作取决于请求的种类和两个接收者的类型

以上述实例为例,假设我们要添加一个 Wait 的状态类,考察 Man 类和 Woman 类的反应,由于使用了双分派,只需增加一个 Action 子类即可在客户端调用即可,不需要改动任何其他类的代码。

🍃访问者模式的注意事项和细节

优点

  1. 访问者模式符合单一职责原则、让程序具有优秀的扩展性、灵活性非常高
  2. 访问者模式可以对功能进行统一,可以做报表、UI、拦截器与过滤器,适用于数据结构相对稳定的系统

缺点

  1. 具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的, 这样造成了具体元素变更比较困难
  2. 违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素

因此,如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的.

资料参考:https://www.bilibili.com/video/BV1G4411c7N4

代码地址:https://gitee.com/WangFuGui-Ma/design-pattern/tree/master/design

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【设计模式】我终于读懂了访问者模式。。。 的相关文章

  • Java复习-25-单例设计模式

    单例设计模式 目的 使用场景 在实际开发下 会存在一种情况 某一种类在程序的整个生命周期中 只需要实例化一次就足够了 例如 系统数据类 由于操作系统只有一个 因此在程序初始化时该类只需要实例化一次 之后的系统数据更改都是在这一个实例化对象中
  • c++享元模式

    享元模式 1 享元模式简介 享元模式在 设计模式 可复用面向对象软件的基础 一书中是这样说的 运用共享技术有效地支持大量细粒度的对象 本质就是对大量细粒度的对象进行共享 不是每个对象都要通过new的方式去创建 而是通过区分对象的内部状态和外
  • 设计模式三: 代理模式(Proxy) -- JDK的实现方式

    简介 代理模式属于行为型模式的一种 控制对其他对象的访问 起到中介作用 代理模式核心角色 真实角色 代理角色 按实现方式不同分为静态代理和动态代理两种 意图 控制对其它对象的访问 类图 实现 JDK自带了Proxy的实现 下面我们先使用JD
  • 行为型模式-策略模式

    package per mjn pattern strategy 抽象策略类 public interface Strategy void show package per mjn pattern strategy 具体策略类 用来封装算法
  • 设计模式之(三)---工厂方法模式

    女娲补天的故事大家都听过吧 这个故事是说 女娲在补了天后 下到凡间一看 哇塞 风景太优美了 天空是湛 蓝的 水是清澈的 空气是清新的 太美丽了 然后就待时间长了就有点寂寞了 没有动物 这些看的到 都是静态的东西呀 怎么办 别忘了是神仙呀 没
  • 设计模式学习笔记(一)之单例模式

    单例模式 作用 保证一个类只有一个实例 并且提供访问这个实例的全局访问点 应用场景有 数据库连接池 spring中 Bean默认是单例 Servlet中 每一个Servlet是单例 配置文件的类 一般是单例 优点 单例只生成一个实例 减少系
  • C++ 装饰器模式

    什么是装饰器模式 装饰器模式是一种结构型设计模式 实现了在不改变现有对象结构的的同时又拓展了新的功能 装饰器本质上是对现有对象的重新包装 同时装饰器又称为封装器 如何理解装饰器模式 以笔记本电脑为例 当我们购买了一台新笔记本电脑 但我们发现
  • 设计模式的 C++ 实现---工厂方法模式(二)

    前文回顾 单例模式 一 单例模式 二 观察者模式 简单工厂模式 工厂方法模式 一 前言 对于工厂方法模式 当增加新产品时 也需要对应增加一个工厂类 可以使用模版进行封装 减少代码工作量 实现举例 产品抽象基类 class Animal pu
  • 计算资源合并模式——云计算架构常用设计模式

    背景 云计算的解决方案中 最初设计可能有意遵循关注点分离的设计原则 把操作分解为独立的计算单元以便可以单独托管和部署 然而 虽然这种策略可以帮助简化解决方案的逻辑实现 但是在同一个应用程序中要部署大量的计算单元 这会增加运行时的托管成本 并
  • 设计模式(5)-适配器模式(Adapter Pattern)

    适配器模式 Adapter Pattern 顾名思义 就像变压器 转接头差不多 就像美国的生活电压是110V 中国是220V 就需要一个变压器将220V转换成110V 或者一个Type C接口想插如USB接口的东西 你就需要一个转换器 而这
  • 第12课:生活中的构建模式——想要车还是庄园

    用程序来模拟生活 从剧情中思考构建模式 与工厂模式的区别 与组合模式的区别 构建模式的模型抽象 类图 基于升级版的实现 模型说明 应用场景 故事剧情 下周就要过年了 这是 Tony 工作后的第一个春节 还是在离家这么远的北京工作 所以肯定不
  • 设计模式--提供者模式provider

    设计模式 C 提供者模式 Provider Pattern 介绍 为一个API进行定义和实现的分离 示例 有一个Message实体类 对它的操作有Insert 和Get 方法 持久化数据在SqlServer数据库中或Xml文件里 根据配置文
  • 设计模式之享元模式

    享元模式 就是共享技术 对于系统中存在大量相同的对象 把他们抽取成一个对象放在缓存中进行使用 这样可以大大节省系统资源 例如 围棋棋盘上有两种棋子 一个是黑子 一个是白子 如果在下棋的时候每下一个棋子就要new一个棋子对象 那么就会有大量的
  • 【设计模式】工厂模式(Factory Pattern)

    1 概述 工厂模式 Factory Pattern 是最常用的设计模式之一 它属于创建类型的设计模式 它提供了一种创建对象的最佳方式 在工厂模式中 我们在创建对象时不会对客户端暴露创建逻辑 并且是通过一个共同的接口来指向新创建的对象 工厂模
  • Java监听器与观察者模式

    Java监听器与观察者模式 Java中的监听器 Listener 和观察者模式 Observer Pattern 都是用于处理对象间的事件通知和响应的设计模式 它们的目的是在对象之间建立一种松散的耦合 使得一个对象的状态变化可以通知到其他对
  • 自动化测试面试题(附答案)

    1 自动化代码中 用到了哪些设计模式 单例设计模式 工厂模式 PO设计模式 数据驱动模式 面向接口编程设计模式 2 什么是断言 Assert 断言Assert用于在代码中验证实际结果是不是符合预期结果 如果测试用例执行失败会抛出异常并提供断
  • C++设计模式 #3策略模式(Strategy Method)

    动机 在软件构建过程中 某些对象使用的的算法可能多种多样 经常改变 如果将这些算法都写在类中 会使得类变得异常复杂 而且有时候支持不频繁使用的算法也是性能负担 如何在运行时根据需求透明地更改对象的算法 将算法和对象本身解耦 从而避免上述问题
  • 自动化测试面试题(附答案)

    1 自动化代码中 用到了哪些设计模式 单例设计模式 工厂模式 PO设计模式 数据驱动模式 面向接口编程设计模式 2 什么是断言 Assert 断言Assert用于在代码中验证实际结果是不是符合预期结果 如果测试用例执行失败会抛出异常并提供断
  • 【设计模式之美】 SOLID 原则之五:依赖反转原则:将代码执行流程交给框架

    文章目录 一 控制反转 IOC 二 依赖注入 DI 三 依赖注入框架 DI Framework 四 依赖反转原则 DIP 一 控制反转 IOC 通过一个例子来看一下 什么是控制反转 public class UserServiceTest
  • C++设计模式 --1.工厂模式和单例模式

    文章目录 1 工厂模式 简单工厂模式 工厂方法模式 抽象工厂模式 2 单例模式 懒汉式 饿汉式 1 工厂模式 简单工厂模式

随机推荐

  • 字符串处理memchr和memrchr

    memchr extern void memchr const void buf int ch size t count 功能 xff1a 从buf所指内存区域的前count个字节查找字符ch 说明 xff1a 当第一次遇到字符ch时停止查
  • 计算多轴飞行器最大悬停时间

    以结果为导向 xff1a 先看下面截图 为了方便看清楚 xff0c 下面截图承接上面截图的 悬停时间公式 xff1a 电池容量 每个电机总电流之和 61 悬停时间 以上面第一个为例 电池容量为22000maH 每个电机总电流之和是什么意思呢
  • linux应用之make命令详解

    从源代码安装过软件的朋友一定对 configure amp amp make amp amp make install 安装三步曲非常熟悉了 然而究竟这个过程中的每一步幕后都发生了些什么呢 xff1f 今天小编将带你一探究竟 深入理解这个过
  • github 之 下载历史版本

    1 打开github中要下载的项目 2 点击commits 点击上图中标记的地方 xff0c 进入下图所示 xff1a 3 选择列表中的某个版本 4 Browse Files 5 下载 点击上图中的 Download ZIP 下载 转载于
  • Linux环境C程序设计(第2版)

    2019独角兽企业重金招聘Python工程师标准 gt gt gt Linux 环境 C 程序设计 xff08 第 2 版 xff09 共分 6 篇 第 1 篇 介绍了 Linux 系统的安装及 LinuxC 开发环境的搭建等 xff1b
  • 如何准备校招技术面试

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 如何准备校招技术面试 标签 xff1a 面试 TOC 2017 年互联网校招已近尾声 xff0c 作为一个非 CS 专业的应届生 xff0c 零 ACM 经验 零期刊论文发
  • vscode添加prettier格式化自动加分号问题

    在vscode的settings json中添加 xff1a 34 prettier singleQuote 34 true 34 prettier semi 34 false 不管别人有没有用 xff0c lz没用 切实有效 xff1a
  • 一个蚂蚁前端曾经的辛酸面试历程 | 掘金技术征文

    正好处在秋招 xff0c 我也来分享我自学校到现在的一些面试经历 本文就不分享具体的面试题了 xff0c 主要讲我这几年的面试经历 xff0c 以及我个人觉得可以从中吸取的经验教训 xff0c 希望能给在上大学以及毕业3年以内的同学提供一点
  • Nodejs 使用log4js日志

    一 创建log4 js文件 xff0c 保存日志到log文件 xff0c 并在控制台输出 xff0c 如果不控制台输出 xff0c 把删除红色的代码 const log4js 61 require 39 log4js 39 path 61
  • 【Spring Cloud Alibaba】Nacos config的使用和高阶用法

    文章目录 x1f40d 第一步 xff0c 创建配置文件到nacos中 x1f40d 第二步 xff0c 在项目中配置nacos的地址和指定文件 x1f40d 第三步 xff0c 读取配置文件 x1f426 高阶用法 x1f426 高阶用法
  • WEBPACK + JSP 构建多页应用

    概述 传统的JSP页面应用无法有效的使用ES6语法特性 xff0c 项目打包压缩困难 xff0c 无法热更新 传统的单页应用在Tomcat等容器下无法进行服务端渲染到达SEO的效果 本项目工程很好融合的传统JSP页面服务端渲染的特点和单页应
  • 0-c语言入门这一篇就够了-学习笔记(一万字)

    内容来自慕课网 xff0c 个人学习笔记 加上了mtianyan标签标记知识点 C语言入门 gt Linux C语言编程基本原理与实践 gt Linux C语言指针与内存 gt Linux C语言结构体 mark https www imo
  • c语言编程求两个整数的最大公约数(两种方法)

    第一种 xff08 for循环 xff09 include lt stdio h gt include lt stdlib h gt int main int i min k a b printf 34 请输入两个整数 n 34 scanf
  • 手机内存LPDDR4X、LPDDR4、LPDDR3的区别 ICMAX告诉你

    现在的智能手机基本人手一部了 xff0c 手机与生活的参与度越来越紧密 xff0c 像学习工作 商务娱乐 支付等 xff0c 基本都能在手机端实现 现在我们买手机时也会更加关注这个手机处理器是什么 xff1f 运行速度快不快这类问题 xff
  • kali安装火狐浏览器

    第一步 xff1a apt get remove iceweasel 第二步 xff1a echo e 34 ndeb http downloads sourceforge net project ubuntuzilla mozilla a
  • 【Kubernetes】The connection to the server <master>:6443 was refused - did you specify the right host ...

    不知道怎么用着用着 xff0c 使用kubectl 时报错 xff0c 错误如下 xff1a root 64 R740 2 2 kubectl get pod The connection to the server 107 105 136
  • 自己动手不求人 - 手工Ghost安装xp、win7系统教程

    由于初级阶段的基本国情 xff0c 很多朋友第一次安装系统大多是用的ghost光盘 xff0c 设置好启动项 xff0c 放进光驱 xff0c 重启后选择安装XX到C盘 xff0c 整个系统就完成了 xff0c 方便快捷 在U盘启动越来越流
  • Security Definitions

    PeopleSoft security is designed around three definition types Permission Lists A set of access rights to application obj
  • 【转】成为Java顶尖程序员 ,看这10本书就够了

    学习的最好途径就是看书 xff0c 这是我自己学习并且小有了一定的积累之后的第一体会 个人认为看书有两点好处 xff1a 1 能出版出来的书一定是经过反复的思考 雕琢和审核的 xff0c 因此从专业性的角度来说 xff0c 一本好书的价值远
  • 【设计模式】我终于读懂了访问者模式。。。

    x1f330 测评系统的需求 将观众分为男人和女人 xff0c 对歌手进行测评 xff0c 当看完某个歌手表演后 xff0c 得到他们对该歌手不同的评价 评价 有不同的种类 xff0c 比如 成功 失败 等 传统方案 x1f331 传统方式