【设计模式-行为型】访问者模式

一、什么是访问者模式

        说起来访问者模式,其实很少用。我一直在思考该用什么样的例子把这个设计模式表述清晰,最近突然想到一个例子也许他就是访问者。港片有过很辉煌的年代,小的时候一直在看港片觉得拍的非常好,而且演员的演技也在线。 不知道大家看没有看过一个金典的穿越剧----《寻秦记》,其中的项少龙(古天乐)就是专业的访问者。项少龙的经历可以很好地体现访问者模式的核心思想。项少龙作为一个现代人,穿越到战国时期,他的角色可以被视为“访问者”,而战国时期的各种人物和事件可以被视为“元素”。项少龙与这些元素的交互“不改变历史结构,添加新的操作”,触发了一系列的变化和故事发展。

访问者模式在《寻秦记》中的体现

  1. 主角作为访问者:项少龙从21世纪穿越到战国时期,他的任务是寻找并保护嬴政,确保历史的正常发展。在这个过程中,他作为“访问者”,与战国时期的各种人物和事件进行交互。

  2. 元素的多样性:战国时期的人物和事件可以被视为“元素”,例如嬴政、乌廷芳、琴清、嫪毐等。每个元素都有其独特的属性和行为,项少龙需要与这些元素进行交互,以完成他的任务。

  3. 交互触发变化:项少龙与这些元素的交互,触发了一系列的变化。例如,他帮助嬴政成长,与乌廷芳和琴清建立了深厚的情感联系。这些交互不仅影响了项少龙自身,也影响了战国时期的历史进程。

  4. 历史轨迹的复杂性:尽管项少龙试图改变历史,但他最终发现历史的轨迹非常复杂,无法轻易改变。这体现了访问者模式中,访问者对元素的操作可能会受到元素自身复杂性的限制。

        访问者模式通过将操作(项少龙和战国时期任务和事件的交互)从对象结构(战国的历史轨迹)中分离出来,封装在访问者(项少龙)类中,使得可以在不修改对象结构的情况下为对象添加新的操作。这种模式特别适用于需要对对象结构中的元素执行多种操作的场景。

二、为什么用访问者模式

        我们来通过上述例子来看看为什么要使用访问者呢,或者什么样的场景使用到了访问者:

  1. 扩展性强:访问者模式能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。在《寻秦记》中,项少龙可以尝试不同的策略和方法来影响历史,而不需要改变历史本身的结构。

  2. 集中管理复杂逻辑:访问者模式将对各个元素的一组操作集中在一个访问者类当中。项少龙的行动和决策都围绕着他的目标展开,使得他的行为更加有条理和系统化。

  3. 解耦数据结构和操作:在《寻秦记》中,项少龙作为访问者,与战国时期的各种人物和事件(元素)进行交互,而不需要改变这些元素本身的结构。这使得项少龙可以灵活地尝试不同的策略,而不会对历史结构本身造成不可逆的影响。

  4. 支持多种操作:访问者模式允许在不修改对象结构的情况下,为对象结构中的元素添加新的操作。项少龙可以尝试多种方法来影响历史,例如通过政治手段、军事手段或情感手段,而不需要改变历史本身的结构。

  5. 对象结构比较稳定,但经常需要在此对象结构上定义新的操作

  6. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类

三、访问者模式示例

        下面我们拿项少龙的经历用代码带输出示例

1. 定义元素接口(各种任务或者事件的统一行为,必须接受访问者)(Element)

public interface Element {void accept(Visitor visitor);
}

2.实现具体元素类(具体的事件或者人物,比如嬴政)(ConcreteElement)

public class YingZheng implements Element {@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public void growWithXiangShaolong() {System.out.println("嬴政在项少龙的帮助下成长为一代帝王。");}
}public class WuTingFang implements Element {@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public void developRelationshipWithXiangShaolong() {System.out.println("乌廷芳与项少龙建立了深厚的情感联系。");}
}public class LaoAi implements Element {@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public void confrontXiangShaolong() {System.out.println("嫪毐与项少龙发生冲突。");}
}

3、定义访问者接口(访问者的统一行为)(Visitor)

public interface Visitor {void visit(YingZheng yingZheng);void visit(WuTingFang wuTingFang);void visit(LaoAi laoAi);
}

4. 实现具体访问者类(主角项少龙)(ConcreteVisitor) 

public class XiangShaolongVisitor implements Visitor {@Overridepublic void visit(YingZheng yingZheng) {yingZheng.growWithXiangShaolong();}@Overridepublic void visit(WuTingFang wuTingFang) {wuTingFang.developRelationshipWithXiangShaolong();}@Overridepublic void visit(LaoAi laoAi) {laoAi.confrontXiangShaolong();}
}

5、场景复现(穿越大戏开始)

public class Main {public static void main(String[] args) {// 创建具体元素对象Element yingZheng = new YingZheng();Element wuTingFang = new WuTingFang();Element laoAi = new LaoAi();// 创建具体访问者对象Visitor xiangShaolong = new XiangShaolongVisitor();// 执行操作yingZheng.accept(xiangShaolong);wuTingFang.accept(xiangShaolong);laoAi.accept(xiangShaolong);}
}//输出
嬴政在项少龙的帮助下成长为一代帝王。
乌廷芳与项少龙建立了深厚的情感联系。
嫪毐与项少龙发生冲突。

        通过这个代码示例,我们可以清晰地看到访问者模式的核心优势。访问者模式通过将操作从对象结构中分离出来,封装在访问者类中,使得可以在不修改对象结构的情况下为对象添加新的操作。这种模式特别适用于需要对对象结构中的元素执行多种操作的场景,例如项少龙在战国时期与不同角色的交互。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/894220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法题(53):对称二叉树

审题: 需要我们判断二叉树是否满足对称结构,并返回判断结果 思路: 方法一:递归 其实是否对称分成两部分判断 第一部分:根节点是否相等 第二部分:根节点一的左子树和根节点二的右子树是否相等,根…

Java知识速记:深拷贝与浅拷贝

Java知识速记:深拷贝与浅拷贝 什么是浅拷贝? 浅拷贝指的是创建一个新对象,但新对象的属性值是对原对象属性值的引用。当原对象的属性是基本类型时,浅拷贝能够直接复制其值;当属性是对象时,仅复制引用&…

使用 cmake

使用前注意 : CMake是一种跨平台的构建系统,它用于管理软件构建过程,尤其适合多语言、多配置的项目。CMake不直接构建软件,而是生成特定构建工具(如Makefile或Visual Studio项目)所需的配置文件。 如果仅仅使用 qt 编…

数据结构【单链表操作大全详解】【c语言版】(只有输入输出为了方便用的c++)

单链表操作的C/C实现详解 在数据结构中,单链表是一种非常基础且重要的数据结构。它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。今天我们就来深入探讨用C/C实现的单链表及其各种操作。 一、单链表的定义 const int N 1e5; //单链表 t…

AI软件外包需要注意什么 外包开发AI软件的关键因素是什么 如何选择AI外包开发语言

1. 定义目标与需求 首先,要明确你希望AI智能体做什么。是自动化任务、数据分析、自然语言处理,还是其他功能?明确目标可以帮助你选择合适的技术和方法。 2. 选择开发平台与工具 开发AI智能体的软件时,你需要选择适合的编程语言、…

第28章 星骗计划的开篇

深夜,万籁俱寂,世界仿佛被按下了静音键。东方艾艾独自坐在窗前,月光如银纱般倾洒在屋内,给一切都蒙上了一层梦幻的色彩。这时,小谷的声音在他脑海里悠悠响起:“主人,咱们所长虽年事已高&#xf…

如何将IP切换到海外:详细指南

在现代互联网应用中,IP地址成为了网络通信和数据交换的基础。然而,很多时候,由于区域限制或隐私保护的需求,用户可能需要将自己的IP地址切换到海外。无论是为了绕过地域限制访问内容,还是为了提高隐私安全,…

学习数据结构(5)单向链表的实现

(1)头部插入 (2)尾部删除 (3)头部删除 (4)查找 (5)在指定位置之前插入节点 (6)在指定位置之后插入节点 (7)删除…

深入理解MySQL 的 索引

索引是一种用来快速检索数据的一种结构, 索引使用的好不好关系到对应的数据库性能方面, 这篇文章我们就来详细的介绍一下数据库的索引。 1. 页面的大小: B 树索引是一种 Key-Value 结构,通过 Key 可以快速查找到对应的 Value。B 树索引由根页面(Root&am…

Vue-cli 脚手架搭建

安装node.js 官网下载node.js安装包,地址:Node.js — Download Node.js 先在node.js即将要安装的路径下创建两个文件夹:node_cache(缓存)、node_global(全局) 点击安装包&#xf…

深度解析 DeepSeek R1:强化学习与知识蒸馏的协同力量

DeepSeek-R1 的问世,无疑在 AI 领域激起了千层浪。自发布仅一周,它便凭借卓越的性能和创新的技术,成为 AI 社区热议的焦点,代表着人工智能在推理和理解能力上的重大飞跃。今天我们一起深度解析一下DeepSeek-R1 一、强大基石&…

openssl 生成证书 windows导入证书

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…

什么是词嵌入?Word2Vec、GloVe 与 FastText 的区别

自然语言处理(NLP)领域的核心问题之一,是如何将人类的语言转换成计算机可以理解的数值形式,而词嵌入(Word Embedding)正是为了解决这个问题的重要技术。本文将详细讲解词嵌入的概念及其经典模型(Word2Vec、GloVe 和 FastText)的原理与区别。 1. 什么是词嵌入(Word Em…

笔记本搭配显示器

笔记本:2022款拯救者Y9000P,显卡RTX3060,分辨率2560*1600,刷新率:165Hz,无DP1.4口 显示器:2024款R27Q,27存,分辨率2560*1600,刷新率:165Hz &…

在php中怎么打开OpenSSL

(点击即可进入聊天助手) 背景 在使用php做一些项目时,有用到用户邮箱注册等,需要开启openssl的能力 在php系统中openssl默认是关闭状态的,在一些低版本php系统中,有的甚至需要在服务器终端后台,手动安装 要打开OpenSSL扩展,需要进行以下步骤 …

【单细胞第二节:单细胞示例数据分析-GSE218208】

GSE218208 1.创建Seurat对象 #untar(“GSE218208_RAW.tar”) rm(list ls()) a data.table::fread("GSM6736629_10x-PBMC-1_ds0.1974_CountMatrix.tsv.gz",data.table F) a[1:4,1:4] library(tidyverse) a$alias:gene str_split(a$alias:gene,":",si…

Docker小游戏 | 使用Docker部署RPG网页小游戏

Docker小游戏 | 使用Docker部署RPG网页小游戏 前言一、项目介绍项目简介项目预览二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署RPG网页小游戏下载镜像创建容器检查容器状态检查服务端口安全设置四、访问RPG网页小游戏五、总结前言 随着互联网技术的不断…

如何把一个python文件打包成一步一步安装的可执行程序

将一个 Python 文件打包成可执行程序(如 .exe 文件),并实现一步一步的安装过程,通常需要以下步骤: 1. 将 Python 文件打包成可执行文件 使用工具将 Python 脚本打包成可执行文件(如 .exe)。常用…

K8S 快速实战

K8S 核心架构原理: 我们已经知道了 K8S 的核心功能:自动化运维管理多个容器化程序。那么 K8S 怎么做到的呢?这里,我们从宏观架构上来学习 K8S 的设计思想。首先看下图: K8S 是属于主从设备模型(Master-Slave 架构),即有 Master 节点负责核心的调度、管理和运维,Slave…

setupdd!SpAppendDiskTag函数分析之末尾添加字符串

setupdd!SpAppendDiskTag函数分析之末尾添加字符串 SpAppendDiskTag函数运行之前, 0: kd> db 0xe108a07c e108a07c 31 00 35 00 33 00 35 00-34 00 20 00 4d 00 42 00 1.5.3.5.4. .M.B. e108a08c 20 00 44 00 69 00 73 00-6b 00 20 00 30 00 20 00 .D.…