“ 访问者设计模式学习心得分享”
适用于结构相对稳定的条目或者xxx对比时,其它相对稳定的层级组织架构使用该模式是OK滴
如条目中文件文件夹的访问,男人女人对同一件事情不同反应的对比
条目只分为文件和文件夹,人只分为男人和女人,这称之为结构稳定。
talk is cheap ,show me the code. 先看一张类图

jdk 使用到的访问者模式示例
java.nio.file.FileVisitor
java.nio.file.Files#walkFileTree

 Path directory = Paths.get("target/perf-logs/");//作用:删除文件下的所有目录及文件,并将该文件夹也删掉if (Files.exists(directory)) {Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.delete(file);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {Files.delete(dir);return FileVisitResult.CONTINUE;}});

自定义MyElement 接口

package design_pattern.visitor.visitor2;
/*** 元素接口*/
public interface MyElement {void accept(Visitor visitor);
}

MyEntry 条目抽象类

package design_pattern.visitor.visitor2;import java.util.Iterator;/*** 条目抽象类*/
public abstract class MyEntry implements MyElement {public abstract String getName();public abstract int getSize();public abstract void printList(String prefix);public void printList() {printList("");}public MyEntry add(MyEntry entry) throws RuntimeException {throw new RuntimeException();}public Iterator iterator() throws RuntimeException {throw new RuntimeException();}public String toString() {return getName() + "<" + getSize() + ">";}
}

MyFile 自定义文件类

package design_pattern.visitor.visitor2;/*** 自定义文件类*/
public class MyFile extends MyEntry {private String name;private int size;public MyFile(String name, int size) {this.name = name;this.size = size;}@Overridepublic String getName() {return name;}@Overridepublic int getSize() {return size;}@Overridepublic void printList(String prefix) {System.out.println(prefix + "/" + this);}@Overridepublic void accept(Visitor visitor) {//重点代码visitor.visit(this);}}

MyDirectory 自定义目录类

package design_pattern.visitor.visitor2;import java.util.ArrayList;
import java.util.Iterator;/*** 自定义目录类*/
public class MyDirectory extends MyEntry {private String name;private ArrayList entrys = new ArrayList();public MyDirectory(String name) {this.name = name;}@Overridepublic String getName() {return name;}@Overridepublic int getSize() {int size = 0;Iterator it = entrys.iterator();while (it.hasNext()) {size += ((MyEntry) it.next()).getSize();}return size;}@Overridepublic MyEntry add(MyEntry entry) {entrys.add(entry);return this;}@Overridepublic Iterator iterator() {return entrys.iterator();}@Overridepublic void printList(String prefix) {System.out.println(prefix + "/" + this);//用for 遍历迭代器写法 快捷键itco,今晚刚发现滴for (Iterator iterator = entrys.iterator(); iterator.hasNext(); ) {MyEntry entry = (MyEntry) iterator.next();entry.printList(prefix + "/" + name);}}@Overridepublic void accept(Visitor visitor) {//重点代码visitor.visit(this);}}

Visitor 抽象访问者

package design_pattern.visitor.visitor2;/*** 抽象访问者*/
public abstract class Visitor {/*** 访问文件* @param myFile*/public abstract void visit(MyFile myFile);/*** 访问目录** @param directory*/public abstract void visit(MyDirectory directory);}

FileFoundVisitor 查找指定文件访问者

package design_pattern.visitor.visitor2;import java.util.ArrayList;
import java.util.Iterator;/*** 查找指定文件访问者*/
public class FileFoundVisitor extends Visitor {private String currentDir = "";private String suffix;private ArrayList files = new ArrayList();public FileFoundVisitor(String suffix) {this.suffix = suffix;}@Overridepublic void visit(MyFile myFile) {if (myFile.getName().endsWith(suffix)) {files.add(currentDir + "/" + myFile);}}public void visit(MyDirectory directory) {//先保存当前目录String saveDir = currentDir;//当前目录被改变currentDir += ("/" + directory.getName());Iterator it = directory.iterator();while (it.hasNext()) {MyEntry entry = (MyEntry) it.next();entry.accept(this);}//将当前目录改回来currentDir = saveDir;}public Iterator getFoundFiles() {return files.iterator();}}

ListVisitor 查找所有文件访问者

package design_pattern.visitor.visitor2;import java.util.Iterator;/*** 查找所有文件访问者*/
public class ListVisitor extends Visitor {String currentDir = "";public void visit(MyFile myFile) {System.out.println(currentDir + "/" + myFile);}public void visit(MyDirectory directory) {System.out.println(currentDir + "/" + directory);String saveDir = currentDir;currentDir += ("/" + directory.getName());Iterator it = directory.iterator();while (it.hasNext()) {MyEntry entry = (MyEntry) it.next();entry.accept(this);}currentDir = saveDir;}}

ObjectStructure 对象结构

package design_pattern.visitor.visitor2;import java.util.ArrayList;
import java.util.Iterator;/*** 对象结构*/
public class ObjectStructure extends ArrayList<MyElement> implements MyElement {@Overridepublic void accept(Visitor visitor) {//调用ArrayList的iterator方法for (Iterator<MyElement> iterator = this.iterator(); iterator.hasNext(); ) {MyElement element = iterator.next();element.accept(visitor);}}
}

Main 客户端

package design_pattern.visitor.visitor2;import java.util.Iterator;/*** 登场角色* >元素*    >>条目*      |--文件*      |--文件夹* >访问者*     |-- 查找指定文件访问者*     |-- 查找所有文件访问者* >对象结构【其实内部就是个封装了ArrayList的容器,加了个accept方法】** <p>* 使用场景:当出现有组织结构、树形结构、多层级访问、问答场景 需要访问各个条目时,可以考虑用使用访问者设计模式* 相关模式:* 1.迭代器设计模式* 2.组合设计模式* <p>* 另外:* MyDirectory#printList(java.lang.String)方法 为我们提供了一种新的递归访问模型* 另外一种新的思路就是像本visitor模式一样使用【双重分发】* <pre>*     public void accept(Visitor visitor) {*         visitor.visit(this);*     }*  <pre/>*  他们是相反的关系,element接收visitor,visitor访问element,*  这种消息分发的方式被称为双重分发【double dispatch】**  为什么要弄得这么复复杂?*  visitor模式的主要目的是将【处理】从数据结构中分离出来,*  【保存数据结构】和【以数据结构为基础】进行处理是两码事*  缺点:*  visitor模式适用于元素基本不变的情况*  添加新的元素非常麻烦*/
public class Main {public static void main(String[] args) {//准备数据MyDirectory root = getData();//处理数据 可以替换为doData 、doData1、doData2doData3(root);}private static void doData3(MyDirectory root) {ObjectStructure objectStructure = new ObjectStructure();objectStructure.add(root);objectStructure.add(new MyFile("我是小孩也是王", 1));objectStructure.accept(new ListVisitor());}/*** 处理数据1:全部访问** @param root*/private static void doData(MyDirectory root) {root.accept(new ListVisitor());}/*** 处理数据2:访问数据并查找指定格式的文文件** @param root*/private static void doData2(MyDirectory root) {FileFoundVisitor visitor = new FileFoundVisitor(".psd");root.accept(visitor);//打印获取到的指定文件Iterator it = visitor.getFoundFiles();while (it.hasNext()) {System.out.println(it.next());}}private static MyDirectory getData() {MyDirectory root = new MyDirectory("根目录");MyDirectory life = new MyDirectory("我的生活");MyFile eat = new MyFile("吃火锅.txt", 100);MyFile sleep = new MyFile("睡觉.html", 100);MyFile study = new MyFile("学习.txt", 100);life.add(eat);life.add(sleep);life.add(study);MyDirectory work = new MyDirectory("我的工作");MyFile write = new MyFile("写博客.doc", 200);MyFile paper = new MyFile("写论文.html", 200);MyFile homework = new MyFile("写家庭作业.docx", 200);work.add(write);work.add(paper);work.add(homework);MyDirectory relax = new MyDirectory("我的休闲");MyFile music = new MyFile("听听音乐.js", 200);MyFile walk = new MyFile("出去转转.psd", 200);relax.add(music);relax.add(walk);MyDirectory read = new MyDirectory("我的阅读");MyFile book = new MyFile("学习书籍.psd", 200);MyFile novel = new MyFile("娱乐小说.txt", 200);read.add(book);read.add(novel);root.add(life);root.add(work);root.add(relax);root.add(read);return root;}}

总结

登场角色

元素 >>条目 |–文件 |–文件夹
访问者 |-- 查找指定文件访问者 |-- 查找所有文件访问者
对象结构【其实内部就是个封装了ArrayList的容器,加了个accept方法】
使用场景:当出现有组织结构、树形结构、多层级访问、问答场景
需要访问各个条目时,可以考虑用使用访问者设计模式

相关模式:
1.迭代器设计模式
2.组合设计模式
另外:MyDirectory#printList(java.lang.String)方法 为我们提供了一种新的递归访问模型 另外一种新的思路就是像本visitor模式一样使用【双重分发】
public void accept(Visitor visitor) {
visitor.visit(this);
}

他们是相反的关系,element接收visitor,visitor访问element,
这种消息分发的方式被称为双重分发【double dispatch】 为什么要弄得这么复复杂?
visitor模式的主要目的是将【处理】从数据结构中分离出来,
【保存数据结构】和【以数据结构为基础】进行处理是两码事
缺点:
visitor模式适用于元素基本不变的情况
添加新的元素非常麻烦



写在最后

总结:本片文章我们主要描述了什么是访问者visitor设计模式,以及使用场景。以及本设计模式相关联的模式:如迭代器设计模式和组合设计模式

,这些都是相互关联的,设计模式是一种套路、是一种模板、是一种经验,是一种角色扮演,每个模式都有其登场角色,我们自己在设计和编程时,要思考一下学习过的设计模,是否适用于当前场景。

正所谓点动成线,线动成面,面动成一片

你现在多努力一份,以后老婆就多漂亮一分,加油吧,少年!!!

23中设计模式之访问者visitor设计模式相关推荐

  1. java中23中设计模式详解

    设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了 ...

  2. 三句话巧记23中设计模式

    大家都知道23中设计模式,其中又可以分成三类,创建型模式,结构型模式,行为型模式.但是总是在实际应用中忘记了,当具体看到一些代码的时候也想不起来具体对应的是哪种设计模式,对经常重构的代码人员来说是一个 ...

  3. Python如何实现单例模式?其他23中设计模式python如何实现?

    单例模式主要有四种方法:new.共享属性.装饰器.import. # __ new__方法:class Singleton(object):def __new__(cls, *args, **kw): ...

  4. 软件设计模式(23中设计模式)

    目录 1. 软件架构设计模式 2. 设计模式特点 3. 设计模式分类 3.1 面向对象设计原则 3.2 5种创建型模式 3.3 7种结构性模式 3.4 11种行为性模式 参考 1. 软件架构设计模式 ...

  5. 史上最详细的23中设计模式解析,一个不落,理论搭配简单案例,更好理解哦

    目录 一.软件设计模式的产生背景 二.软件设计模式的概念与意义 1. 软件设计模式的概念 2. 学习设计模式的意义 三.23 种设计模式的分类和功能 1. 根据目的来分 2. 根据作用范围来分 3. ...

  6. 追MM和23中设计模式(来自网络)

    设计模式做为程序员的"内功心法",越来越受到重视.这是一篇通俗版23种设计模式,用实际生活做比喻,让你很快就能理解其中的深意. 1.FACTORY―追MM少不了请吃饭了,麦当劳的鸡 ...

  7. Java常见的23中设计模式

    工厂模式, 工厂方法模式,单例模式, 外观(Facade)模式, 观察者(Observer)模式,桥接(Bridge)模式都是比较常用的,不同的项目有不同的设计方向,可以参考的设计模式也不尽相同,没有 ...

  8. java中的23中设计模式

    1.工厂模式:客户类和工厂类分开.消费者任何时候需要某种产品,只需向工厂请求即可.消费者无须修改就可以接纳新产品.缺点是当产品修改时,工厂类也要做相应的修改.如:如何创建及如何向客户端提供.   2. ...

  9. 【GOF】23中设计模式深析

    2019独角兽企业重金招聘Python工程师标准>>> ###对象创建 原型模式.工厂模式.抽象工厂模式.生成器.单例模式 ###接口适配 适配器模式.桥接.外观模式.迭代器 ### ...

最新文章

  1. memcpy()函数
  2. Elasticsearch之集群脑裂
  3. 独家 | 一文读懂Apache Kudu
  4. 类型重定义 头文件预编译设置
  5. AI Frontiers | 微软首席 AI 科学家邓力演讲:口语对话系统的分类及三代演变
  6. Boost::context模块callcc的jump_void测试程序
  7. 关于jedis2.4以上版本的连接池配置,及工具类
  8. Facebook 约十亿美元收购脑机技术公司,助攻AR研发;苹果宣布新款 Mac Pro 在美国生产;谷歌称已实现量子霸权…...
  9. 作者:季统凯,男,博士,中国科学院云计算中心主任、研究员,国云科技股份有限公司董事长,中国云计算专家委员会委员。...
  10. 如何更新Node.js?
  11. Maven项目中父子项目互相找不到的解决方法
  12. 用java 解密pdf_Java 加密、解密PDF文档(示例代码)
  13. 2021年物联网设备CVE天梯榜
  14. 快速复现利用Log4j漏洞启动windows计算器
  15. 动态背景下的运动目标检测
  16. Java笔试面试题三(编程算法)
  17. 怎么批量下载Onedrive分享文件_怎么用PS弄字幕文件 PS批量生成字幕制作教程
  18. 无扩展,不 Chrome
  19. 2038:最大数位置(题目来源于信息奥赛一本通官网)
  20. 手把手教大家如何给域名申请免费SSL证书

热门文章

  1. Vue之父传子,清晰易懂。
  2. Consul安装使用
  3. c# 实现的命令提示窗口玩快艇骰子游戏程序
  4. Axure8.0教程:换一批(随机)
  5. Linux:如何强制杀死一个进程和杀死多个进程
  6. 深度学习中机器学习策略的运用 Projects-1
  7. C++编写过程中的一些典型错误(持续更新)
  8. react学习—ref
  9. ETL工具(数据同步)
  10. AAAI 2021 最佳论文公布