设计模式笔记_行为型_访问者模式

1. 访问者模式介绍

访问者模式(Visitor Pattern)是一种行为型设计模式,它允许你在不改变对象结构的前提下,定义作用于这些对象的新操作。访问者模式将操作的逻辑从对象结构中分离出来,使得你可以在运行时动态地添加新的操作

类比场景:想象一下,你有一个博物馆,里面有不同的展品(对象结构):绘画、雕塑等。当有不同的访客(访问者,比如艺术爱好者、学生等)来参观时,他们可能希望对展品进行不同的处理或观察(操作)。访问者模式就像是让这些访客带着自己的需求来参观博物馆,而博物馆本身无需改变展品的展示方式。当有新的访问者要进行新的操作时,只需要新增一个访问者即可。

结构组成:

  1. Visitor(访问者接口):定义访问者可以执行的操作;对每种元素类型都有一个方法。
  2. ConcreteVisitor(具体访问者):实现Visitor接口,定义每个元素的具体访问行为。
  3. Element(元素接口):被访问者接口,定义接受访问者的方法。
  4. ConcreteElement(具体元素):实现Element接口,具体定义接受访问者的行为。
  5. Object Structure:包含元素的集合,提供一个可以遍历这些元素的高层接口,并让访问者访问它们。

优缺点分析:

  • 优点
    • 新增操作方便:可以在不修改对象结构的情况下增加新的操作(通过新增visitor实现)。
    • 符合单一职责原则:将不同的操作分离到不同的访问者中。
    • 扩展性好:可以很方便地增加新的访问者。
  • 缺点
    • 对象结构必须稳定:如果对象结构经常改变,维护成本会很高(每个visitor里定义了对所有元素的访问,如果元素发生改变,需要修改所有visitor)。
    • 具体元素更复杂:每个具体元素都需要实现接受访问者的方法。
    • 可能导致类爆炸:如果元素和访问者种类很多,会导致类数量激增。

适用场景:

  • 当对象结构较为稳定,且需要在此结构上定义新的操作时。
  • 当需要对一个对象结构中的对象进行很多不同且不相关的操作时。

2. 代码演示

场景:学生和艺术爱好者(visitor)去博物馆(objectStructure)参观绘画和雕像(element),各类人行为不同。

Visitor(访问者接口):

// Visitor接口:定义一个访问者可以执行的操作
// 包含了对所有具体元素的访问方法
public interface Visitor {void visit(Painting painting);void visit(Sculpture sculpture);
}

ConcreteVisitor(具体访问者):

//具体访问者: 实现Visitor接口,用于定义某种操作
//艺术爱好者的行为
public class ArtLoverVisitor implements Visitor {@Overridepublic void visit(Painting painting) {System.out.println("ArtLoverVisitor visit painting: " + painting.getName());}@Overridepublic void visit(Sculpture sculpture) {System.out.println("ArtLoverVisitor visit sculpture: " + sculpture.getName());}
}//学生的行为
public class StudentVisitor implements Visitor {@Overridepublic void visit(Painting painting) {System.out.println("StudentVisitor visit painting: " + painting.getName());}@Overridepublic void visit(Sculpture sculpture) {System.out.println("StudentVisitor visit sculpture: " + sculpture.getName());}
}

Element(元素接口)

// Element接口:被访问对象,定义接受访问者的接口
public interface Exhibit {void accept(Visitor visitor);
}

ConcreteElement(具体元素):

// 具体元素: 实现Element接口,定义接受访问者的操作
// 绘画
public class Painting implements Exhibit {private String name;public Painting(String name) {this.name = name;}public String getName() {return name;}@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}//雕像
public class Sculpture implements Exhibit {private String name;public Sculpture(String name) {this.name = name;}public String getName() {return name;}@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}

Object Structure:

// ObjectStructure:维护元素对象列表,并提供高层方法来遍历操作这些对象
public class Museum {private List<Exhibit> exhibits = new ArrayList<>();public void addExhibit(Exhibit exhibit) {exhibits.add(exhibit);}public void showExhibits(Visitor visitor) {for (Exhibit exhibit : exhibits) {exhibit.accept(visitor);}}
}

客户端:

public class VisitorClientDemo {public static void main(String[] args) {Museum museum = new Museum();museum.addExhibit(new Sculpture("The Thinker"));museum.addExhibit(new Painting("Starry Night"));Visitor visitor1 = new ArtLoverVisitor();museum.showExhibits(visitor1);Visitor visitor2 = new StudentVisitor();museum.showExhibits(visitor2);}
}

对应的类图:

扩展:

上述示例中,将操作(学生/艺术爱好者的行为) 从对象结构(绘画/雕塑等展览)中分离出来了,后续若需添加新的操作(历史专家的行为),只需要新增对应的visitor(HistorianVisitor) 即可。

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

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

相关文章

数学建模 14 中心对数比变换

用途&#xff1a;是处理成分数据的核心预处理方法&#xff0c;核心目标是解决成分数据的和为常数100% &#xff0c; 导致的维度冗余&#xff0c;非线性相关问题。使得数据满足传统的统计/建模方法&#xff1b;举例子&#xff1a;食品比例中 面粉(50%),糖(30%),水(20%)原理&…

【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day7

&#x1f525;个人主页&#xff1a;草莓熊Lotso &#x1f3ac;作者简介&#xff1a;C研发方向学习者 &#x1f4d6;个人专栏&#xff1a; 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》 ⭐️人生格言&#xff1a;生活是默默的坚持&#xff0c;毅力是永久的…

污水处理行业的 “智能革命”:边缘计算网关如何重塑传统运维模式?

污水处理行业的 “智能革命”&#xff1a;边缘计算网关如何重塑传统运维模式&#xff1f;在污水处理这一关乎生态环境与可持续发展的关键领域&#xff0c;蓝蜂网关正凭借其先进技术与强大功能&#xff0c;发挥着无可替代的重要作用。作为工业级物联网解决方案的核心组件&#x…

ASP.NET Core 中的多租户 SaaS 应用程序

介绍随着软件即服务 (SaaS) 持续主导技术领域&#xff0c;构建能够高效地从单一代码库服务于多位客户&#xff08;租户&#xff09;的应用程序变得至关重要。ASP.NET Core 凭借其模块化和可扩展的架构&#xff0c;是实现多租户 SaaS 应用程序的强大框架。本文将指导您了解构建多…

JUC之CompletableFuture【中】

文章目录四、CompletableFuture基本使用4.1 默认线程池、无返回值4.2 默认线程池、有返回值4.3 自定义线程池、有返回值4.4 CompletableFuture 获取结果五、对结果进行处理5.1 方法说明5.2 示例5.3 thenApply vs thenApplyAsync5.3.1 核心区别: 执行线程不同5.3.2 thenApply: 同…

环境变量不生效?

目录 添加环境变量 解决不生效 不生效场景 解决办法 大家都知道Windows系统对于开发者来说并不友好&#xff0c;尤其是新手&#xff0c;当然这是相比于linux和MacOS相比&#xff0c;因为开发工具、项目脚本等环境配置要为复杂&#xff0c;注意事项也更多一些。而这篇文章将…

小迪安全v2023学习笔记(六十六讲)—— Java安全SQL注入SSTISPELXXE

文章目录前记WEB攻防——第六十六天Java安全&SPEL表达式&SSTI模板注入&XXE&JDBC&MyBatis注入环境搭建Hello-Java-SecJavaSecJava安全 - SQL注入-JDBC&MyBatisJDBC注入原理语句拼接预编译的错误使用JdbcTemplate正则过滤MyBatis注入原理Like注入Order B…

把 AI 变成「图书馆管理员」——基于检索增强的离线图书语音导航小盒子

标签&#xff1a;检索增强、语音导航、离线 LLM、RAG、ESP32-S3、低功耗、TTS、BLE ---- 1. 背景&#xff1a;读者找不到书的痛苦 高校图书馆每天 5000 人次&#xff0c;高频问题&#xff1a; • “《深度学习》在哪个书架&#xff1f;” • “有没有类似《三体》的科幻&…

架构思维:在AI时代为产品“减负”的终极武器——用结构化智慧破解数字化复杂困局

摘要 数字化产品的复杂度飙升已成为企业发展的核心瓶颈。本文基于架构思维的本质&#xff08;元素、连接、演进&#xff09;&#xff0c;结合5A架构体系&#xff08;业务/信息/应用/技术/治理架构&#xff09;&#xff0c;系统阐述如何通过分而治之、共性沉淀、AI赋能三大策略降…

黎阳之光:以数字之力,筑牢流域防洪“智慧防线”

当洪水来袭&#xff0c;每一分精准的预报、每一次及时的预警、每一轮科学的预演、每一套完善的预案&#xff0c;都可能关系到江河安澜与万家平安。在水利现代化建设的浪潮中&#xff0c;黎阳之光凭借数字孪生、视频孪生等核心技术&#xff0c;打造流域防洪“四预”管理平台&…

transformer模型初理解

模型介绍 在 Transformer 之前&#xff0c;主流的序列模型是 **RNN&#xff08;循环神经网络&#xff09;** 工作方式类似「逐字阅读」&#xff1a;处理序列时&#xff0c;必须从第一个词开始&#xff0c;一个接一个往后算&#xff08;比如翻译时&#xff0c;先看 “我”&#…

驱动开发系列66 - glCompileShader实现 - GLSL中添加内置函数

一&#xff1a;概述 本文介绍如何为 GLSL 语言中增加一个内置函数&#xff0c;以https://registry.khronos.org/OpenGL/extensions/ARB/ARB_shader_texture_image_samples.txt扩展为例&#xff0c;介绍下添加textureSamples内置函数的过程。

指针的应用学习日记

Git常见的命令&#xff1a;%h 简化哈希 %an 作者名字 %ar 修订日期(距今) %ad修订日期 %s提交说明指针简介指针(Pointer)是C语言的一个重要知识点&#xff0c;其使用灵活、功能强大&#xff0c;是C语言的灵魂。 指针与底层硬件联系紧密&#xff0c;使用指针可操作数据的地址&am…

KMM跨平台叛逃实录:SwiftUI与Compose Multiplatform共享ViewModel的混合开发框架(代码复用率85%)

KMM跨平台叛逃实录&#xff1a;SwiftUI与Compose Multiplatform共享ViewModel的混合开发框架&#xff08;代码复用率85%&#xff09;一、架构革命&#xff1a;跨平台统一状态管理1.1 核心架构设计1.2 技术矩阵对比二、KMM共享ViewModel实现2.1 基础状态管理2.2 ViewModel核心架…

关于Android webview协议混淆

背景&#xff1a;android中引入的html页面是http请求(web服务仅开放了80端口)&#xff0c;但html页面引用的后端接口是https请求&#xff0c;则发生android中html页面请求接口异常<请求无法发送到后端服务(status0)>。浏览器出于安全考虑&#xff0c;要求&#xff1a; 同…

Android Jetpack | Lifecycle

一.前言 本篇主线包含三点&#xff0c;Lifecycle的作用、简单使用、核心原理&#xff08;包含核心类与源码主线分析&#xff09;&#xff1b; 二.作用 官方文档生命周期感知型组件可执行操作来响应另一个组件&#xff08;如 Activity 和 Fragment&#xff09;的生命周期状态…

单片机编程架构

没有最好的程序架构。 只要在项目中实现产品功能并稳定工作&#xff0c;且能在团队内统一应用管理就是最优的程序架构。 一、单片机运行模型&#xff1a; 1.能分配时间的裸机代码 2.FreeRTOS操作系统 代码分层框架&#xff1a; 1.与板关联的底层 2.《驱动底层的驱动层》《中间层…

114. 二叉树展开为链表

题目&#xff1a;给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。…

【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统

Langchain二次开发专栏 【Langchain系列一】常用大模型的key获取与连接方式 【Langchain系列二】LangChain+Prompt +LLM智能问答入门 【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统 【Langchain系列四】RAG——基于非结构化数据库的智能问…

【GNSS定位原理及算法杂记6】​​​​​​PPP(精密单点定位)原理,RTK/PPK/PPP区别讨论

PPP 技术详解&#xff1a;原理、流程与 RTK/PPK 对比 在高精度 GNSS 定位技术体系中&#xff0c;除了 RTK 和 PPK 以外&#xff0c;还有一类无需基站即可实现分米到厘米级定位的方法 —— PPP&#xff08;Precise Point Positioning&#xff0c;精密单点定位&#xff09;。它以…