访问者模式(数据与行为解耦)
目录
前言
UML
plantuml
类图
实战代码
SimpleFileVisitor
FileVisitor 接口
删除指定文件夹
模板
IVisitor
IVisitable
Client
前言
一个类由成员变量和方法组成,成员变量即是类的数据结构,方法则是类的行为。
如果一个类的数据结构稳定,但是行为多变,想要增加类的行为,就必须为类添加新的方法,违背了开闭原则。
使用访问者模式,则可以在不修改原有类的前提下定义新的操作,为类增加新的行为。
它能将类的数据结构和行为解耦,将多变的行为提取到访问者中,不同的访问者实现不同的行为。当类的行为变化时,只需要替换对应的访问者就能够修改类的行为了。
故访问者特别适用于数据结构相对稳定,而操作易于变化的场景。
UML
plantuml
@startuml
'https://plantuml.com/class-diagraminterface Visitable {+ accept(Visitor) : void
}class ConcreteVisitable {+ accept(Visitor) : void
}interface Visitor {+ visit(IVisitable) : void
}class ConcreteVisitorA {+ visit(IVisitable) : void
}class ConcreteVisitorB{+ visit(IVisitable) : void
}class Client {}Visitable <|.. ConcreteVisitable
Visitor <|.. ConcreteVisitorA
Visitor <|.. ConcreteVisitorBVisitable <..> VisitorClient ..> Visitable
Client ..> Visitor@enduml
类图

实战代码
SimpleFileVisitor
JDK 中 nio 的 Files 的 walkFileTree 方法使用了访问者模式来遍历文件树,使用时可以重写 SimpleFileVisitor 中的方法,对文件树下每个文件做相应操作。比如删除文件,复制文件,查找文件等等。
FileVisitor 接口
可以看到 FileVisitor 接口定义了访问文件夹的前置/后置操作,访问文件操作,以及访问文件异常操作,SimpleFileVisitor 则是提供了空实现。
在实际使用时,创建自定义文件访问者类,实现 FileVisitor 接口或者直接继承 SimpleFileVisitor 类,然后实现接口中定义的方法。使用 walkFileTree 遍历文件树时传入不同的访问者则能够对应不同的文件操作逻辑,完美地将数据结构和操作行为分离

删除指定文件夹
public class Client {public static void main(String[] args) throws IOException {Path directory = Paths.get("/data/file/abc");Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {Files.delete(file); // this will work because it's always a Filereturn FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {Files.delete(dir); //this will work because Files in the directory are already deletedreturn FileVisitResult.CONTINUE;}});}}
模板
IVisitor
public interface IVisitor {void visit(IVisitable visitable);
}public class Visitor1 implements IVisitor {public void visit(IVisitable visitable) {System.out.println("Visitor1");}
}public class Visitor2 implements IVisitor {public void visit(IVisitable visitable) {System.out.println("Visitor2");}
}
IVisitable
public interface IVisitable {void accept(IVisitor visitor);
}class Part implements IVisitable {String name;Integer value;public void accept(IVisitor visitor) {visitor.visit(this);}
}
Client
public class Client {public static void main(String[] args) throws IOException {IVisitable part = new Part(); IVisitor visitor1 = new Visitor1();part.accept(visitor1);IVisitor visitor2 = new Visitor2();part.accept(visitor2);}
}
相关文章:
访问者模式(数据与行为解耦)
目录 前言 UML plantuml 类图 实战代码 SimpleFileVisitor FileVisitor 接口 删除指定文件夹 模板 IVisitor IVisitable Client 前言 一个类由成员变量和方法组成,成员变量即是类的数据结构,方法则是类的行为。 如果一个类的数据结构稳定&am…...
LeetCode:1319. 连通网络的操作次数(并查集 Java)
目录 1319. 连通网络的操作次数 题目描述: 实现代码与解析: 并查集 原理思路: 1319. 连通网络的操作次数 题目描述: 用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示…...
C++ STL教程
C STL教程 文章目录 C STL教程1.1 std::vector1.1.1vector的定义1.1.2vector容器的初始化1.1.3vector容器内元素的访问和修改1.1.4vector中的常用函数 1.2 std::string1.2.1string的定义1.2.2string的初始化1.2.3string中元素的访问和修改1.2.4string中连接字符串1.2.5string中…...
系列学习前端之第 6 章:一文掌握 jQuery(熟悉即可)
前言:为什么说 jQuery 熟悉即可,已日渐过时? 作为前端开发中常用的两个库或框架:Vue.js 和 jQuery。不少开发者想要学习 Vue.js 时,都会有一个疑惑:学习 Vue.js 是否一定要学习 jQuery? 从几个…...
python 中判断文件、目录是否存在的方法
判断目录是否存在并创建目录 一、实现上传文件功能二、判断目录是否存在的办法2.1、使用os模块2.1.1、判断目录是否存在2.1.2、os.makedirs():递归创建目录 2.2、使用pathlib模块2.2.1、path.exist()判断目录是否存在2.2.1、path.mkdir():创建目录 2.3、…...
Redis的安装与启动
一、Linux环境安装&启动Redis 1. 安装步骤 第一步:在官网下载好Redis安装包,上传到Linux中并进行解压到相应(如/opt/software/)目录中;(注意:完成了第二步后,即安装了C/C语言…...
WebGIS航线编辑器(无人机航线规划)
无人机航点、航线规划,实现全自动航点飞行作业及飞行航拍。禁飞区、作业区功能保障飞行安全。 GIS引擎加载 const viewer new Cesium.Viewer("cesiumContainer", { imageryProvider: new Cesium.IonImageryProvider({ assetId: 3872 }), }); const im…...
STEP 格式三维模型读取
STEP是常用的三维模型存储格式,使用Express语言描述几何图形,文件存储方式为BRep,分为STEP203和STEP214,后者多了颜色信息,opencascade中提供了相应算法读取STEP文件。 #include <STEPControl_Reader.hxx>TopoD…...
Mora: Enabling Generalist Video Generation via A Multi-Agent Framework
目录 论文地址:Mora: Enabling Generalist Video Generation viaA Multi-Agent Framework github地址:https://github.com/lichao-sun/Mora 一、摘要 (1)Mora 的主要特点: (2)Mora的应用场景…...
[c++] 自写 MyString 类
实现了 MyString 类,同时实现了运算符重载,重载的运算符包括 <、>、、!、<<、>>、[] 等。 如果一个类重载了某个运算符,那么对这个类的对象进行操作的时候便会使用类重载的运算符。比如下边代码 MyString 类中重载了 <、…...
三、阅读器开发--4、阅读器目录、全文搜索功能开发
1、阅读器目录 1.1、实现目录 先实现目录的布局 定义一个蒙版,充满整个屏幕浮在阅读器上方,左侧为目录右侧为背景,目录下方包含一个tab,点击后会切换不同的内容,这里tab是目录、书签,这里可以通过如下的…...
AMEYA360代理 | 江苏长晶科技FST2.0高性能 IGBT产品介绍
江苏长晶科技股份有限公司是一家专业从事半导体产品研发、生产和销售的企业。自2019年起,连续4年被中国半导体行业协会评为 “功率器件十强企业”。2021年开始自主研发有着“工业CPU”之称的IGBT,截至2023年Q3在家电/工业/新能源等行业实现8款产品市场应…...
基于springboot+vue+Mysql的网上图书商城
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
阿里云服务器多少钱一个月?低至5元1个月
阿里云服务器一个月多少钱?最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年,折合5元一个月,2核4G服务器30元3个月,2核2G3M带宽服务器99元12个月,轻量应用服务器2核4G4M带宽165元12个月,4核16G服务…...
LeetCode第五天(442. 数组中重复的数据)
给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。 你必须设计并实现一个时间复杂度为 O(n) 且仅使用常量额外空间的算法解决此问…...
chatgpt正面案例合集
现在可以用百度 百度安全验证 chatgpt用来搜索软件使用指令太牛了_个人渣记录仅为自己搜索用的博客-CSDN博客 chatgpt 使用案例 根据不同的目标群体变更文案和表达_个人渣记录仅为自己搜索用的博客-CSDN博客 倾听能力 和哪些基础能力相关 ,如何提高 chatgpt_个人渣记录仅为自…...
今日讲讲路由配置
下载安装路由 1. 下载安装路由库 npm i vue-router 2. 在 src 中新建 views 文件夹,在其中新建页面 3. 在 src 中新建一个 router 文件夹,其中新建一个 index.js import { createRouter, createWebHashHistory } from vue-router; // 导入页面 imp…...
【Rust】Shared-State Concurrency
Shared-State Concurrency channel类似于single ownership. 而shared memory类似与multiple ownership. multiple ownership是难于管理的. smarter pointer也是multiple ownership的. Rust的type system和ownership rules帮助实现正确的multiple ownership管理。 Using Mute…...
连接数据库(MySQL)的JDBC
目录 JDBC简介快速入门API详解DriverManager(驱动管理类)注册驱动:获取数据库连接(对象): Connection(数据库连接对象)获取执行SQL的对象管理事务 Statement(执行SQL语句)执行DML、DDL语句执行DQL语句 Resu…...
golang通过参数控制HTTP server是否使用基本认证
之前写的《golang实现一个BasicAuth的HTTP server》一定会做基本认证。 本例给出了如何通过启动时候指定的参数来控制是否做基本认证 代码对比和解释 给出与上一篇中源码的diff adminhpc-1:~/go/auth_http$ diff -ruN http_rpc_server.go_bak http_rpc_server.go --- http_rp…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
