26-Java访问者模式 ( Visitor Pattern )

Java访问者模式

    • 摘要
    • 实现
    • 范例

  • 访问者模式(Visitor Pattern)使用了一个访问者类,它改变了元素类的执行算法,通过这种方式,元素的执行算法可以随着访问者改变而改变
  • 访问者模式中,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作
  • 模板模式属于行为型模式

摘要

1. 意图

  • 主要将数据结构与数据操作分离

2. 主要解决

  • 稳定的数据结构和易变的操作耦合问题。

3. 何时使用

  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作”污染”这些对象的类,使用访问者模式将这些封装到类中

4. 如何解决

  • 在被访问的类里面加一个对外提供接待访问者的接口

5. 关键代码

  • 在数据基础类里面有一个方法接受访问者,将自身引用传入访问者

6. 应用实例

  • 您在朋友家做客,您是访问者,朋友接受您的访问,您通过朋友的描述,然后对朋友的描述做出一个判断,这就是访问者模式

7. 优点

  • 符合单一职责原则;
  • 优秀的扩展性;
  • 灵活性;

8. 缺点

  • 具体元素对访问者公布细节,违反了迪米特原则;
  • 具体元素变更比较困难;
  • 违反了依赖倒置原则,依赖了具体类,没有依赖抽象;

9. 使用场景

  • 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作;
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类;

10. 注意事项

  • 访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器

实现

在这里插入图片描述

  • 创建一个定义接受操作的ComputerPart接口;
  • 定义类Keyboard、Mouse、Monitor和Computer实现ComputerPart接口;
  • 定义另一个接口ComputerPartVisitor,它定义了访问者类的操作;
  • 定义类Computer使用实体访问者来执行相应的动作;
  • 定义类VisitorPatternDemo使用Computer、ComputerPartVisitor类来演示访问者模式的用法;

范例

1. 定义一个表示元素的接口

ComputerPart.java

package com.demo.gof;
public interface ComputerPart {
   public void accept(ComputerPartVisitor computerPartVisitor);
}

2. 创建扩展了上述类的实体类

Keyboard.java

package com.demo.gof;
public class Keyboard  implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Monitor.java

package com.demo.gof;
public class Monitor  implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Computer.java

package com.demo.gof;
public class Computer implements ComputerPart {

   ComputerPart[] parts;

   public Computer(){
      parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};      
   } 
   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      for (int i = 0; i < parts.length; i++) {
         parts[i].accept(computerPartVisitor);
      }
      computerPartVisitor.visit(this);
   }
}

3. 定义一个表示访问者的接口

ComputerPartVisitor.java

package com.demo.gof;
public interface ComputerPartVisitor {
    public void visit(Computer computer);
    public void visit(Mouse mouse);
    public void visit(Keyboard keyboard);
    public void visit(Monitor monitor);
}

4. 创建实现了上述类的实体访问者

ComputerPartDisplayVisitor.java

package com.demo.gof;
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {

   @Override
   public void visit(Computer computer) {
      System.out.println("Displaying Computer.");
   }

   @Override
   public void visit(Mouse mouse) {
      System.out.println("Displaying Mouse.");
   }

   @Override
   public void visit(Keyboard keyboard) {
      System.out.println("Displaying Keyboard.");
   }

   @Override
   public void visit(Monitor monitor) {
      System.out.println("Displaying Monitor.");
   }
}

5. 使用 ComputerPartDisplayVisitor 来显示 Computer 的组成部分

VisitorPatternDemo.java

package com.demo.gof;
public class VisitorPatternDemo {
   public static void main(String[] args) {

      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
   }
}

编译运行以上 Java 范例,输出结果如下

$ javac -d . src/main/com.demo/gof/VisitorPatternDemo.java
$ java  com.ddkk.demo.VisitorPatternDemo
Displaying Mouse.
Displaying Keyboard.
Displaying Monitor.
Displaying Computer.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity2019.2.x 导出apk 安装到安卓Android12+及以上的系统版本 安装出现-108 安装包似乎无效的解决办法

Unity2019.2.x 导出apk 安装到安卓Android12及以上的系统版本 安装出现-108 安装包似乎无效的解决办法 导出AndroidStudio工程后 需要设置 build.gradle文件 // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAINbuildscript {repositor…

python-0007-django模版

介绍 模版是对js&#xff0c;html等资源的封装 新建 在项目路径下新建模版文件夹templates&#xff08;可以为其他名称&#xff09;&#xff0c;要是想细分业务的话&#xff0c;还可以在templates路径下继续建文件夹。如下图&#xff1a; 注册模版 在项目的settings找到T…

超越营销:交易性邮件如何塑造现代沟通

在我们的电子邮件自动化系列文章中&#xff0c;我们继续探讨交易性邮件的重要性。这些邮件对于向收件人传递实时更新和可操作信息至关重要&#xff0c;是企业运营不可或缺的一部分。 运营触点 在现代沟通中&#xff0c;交易性邮件扮演着不可或缺的角色&#xff0c;尤其是在企…

String类及其常用方法

文章目录 1.String类的特性与使用1.1 String类的特性1.2 String对象的创建方式1.3 String 的使用&#xff08;不同的拼接操作&#xff09; 2.String常用方法2.1 String的常用方法一2.2 String常用方法二2.3 String常用方法三 1.String类的特性与使用 1.1 String类的特性 Stri…

使用Barrier共享鼠标键盘,通过macos控制ubuntu系统

之前文章写过如何使用barrrier通过windows系统控制ubuntu系统&#xff0c;该文章将详细介绍如何使用barrier通过macos系统控制ubuntu系统 一、macOS安装barrier macOS版本barrier链接 1、双击点开安装包 2、将安装包里的barrier拷贝到macOS的达达->应用程序中 3、在达达…

Spring启动“--”设置参数没生效

现象 在idea中启动SpringBoot项目时&#xff0c;使用“--”设置的启动参数没有生效&#xff0c;如修改端口号“--server.port8082” 原因 排查发现是因为在使用SpringApplication.run启动项目时&#xff0c;没有将args参数传入run方法。 修复方案 SpringApplication.run参数中…

当matplotlib遇见“赛博朋克”

本次分享一个Python可视化工具cyberpunk,轻松让图表变得“赛博朋克”。 案例1 import matplotlib.pyplot as plt import mplcyberpunkplt.style.use("cyberpunk") #调用cyberpunk styleplt.plot([1, 3, 9, 5, 2, 1, 1], marker=o) plt.plot([4, 5, 5, 7, 9, 8, 6…

Linux系统——Nginx脚本拦截拓展

可能会有些无聊的人对服务器的Nginx服务进行恶意访问网站、API接口&#xff0c;会影响到用户的体验&#xff0c;我们可以做一个简单的脚本对恶意访问的IP做一个有效的拦截&#xff0c;揪出这些IP地址&#xff0c;然后将其进行禁用。 在Nginx的conf目录下新建一个blockip.conf文…

Redis第8讲——Cluster集群模式详解

前面两篇文章介绍了Redis主从和哨兵模式&#xff0c;不难发现&#xff0c;它们都有一些共同的缺点&#xff0c;首先在主从切换的过程中会丢失数据&#xff1b;另一个就是只有一个master&#xff0c;只能单点写&#xff0c;并没有水平扩容能力。而且每个节点都保存了所有的数据&…

sqlite3——数据库——day2

今天学习了sqlite3数据库 sqlite3_open sqlite3_openint sqlite3_open(const char *filename, /* Database filename (UTF-8) */sqlite3 **ppDb /* OUT: SQLite db handle */); 功能:打开数据库文件(创建一个数据库连接) 参数:filename:数据库文件路径 ppDb:操作数…

Python使用lxml解析XML格式化数据

Python使用lxml解析XML格式化数据 1. 效果图2. 源代码参考 方法一&#xff1a;无脑读取文件&#xff0c;遇到有关键词的行再去解析获取值 方法二&#xff1a;利用lxml等库&#xff0c;解析格式化数据&#xff0c;批量获取标签及其值 这篇博客介绍第2种办法&#xff0c;以菜鸟教…

如何实现Git Push之后自动部署到服务器?

在平时个人开发的过程中是不是有这样的烦恼&#xff1a; 项目开发完成&#xff0c;Push之后 登录服务器&#xff0c;手动git pull&#xff0c;然后运行部署命令 这真的很烦诶&#xff01; 那么能不能Git push之后&#xff0c;远端服务器自动 Git pull 然后运行部署命令呢&a…

信息系统项目管理师002:信息系统(1信息化发展—1.1信息与信息化—1.1.2 信息系统)

文章目录 1.1.2 信息系统1.信息系统及其特性2.信息系统生命周期 记忆要点总结 1.1.2 信息系统 信息系统是由相互联系、相互依赖、相互作用的事物或过程组成的具有整体功能和综合行为的统一体。在经济与社会活动中&#xff0c;经常使用“系统”的概念&#xff0c;例如&#xff0…

python的函数与类的定义

目录 1.函数 1.函数的定义 2.输入参数与输出参数的类型 3.输入和输出多个参数 1.普通参数 2.含有任意数量的参数 3.关键字参数 4.普通参数与多个参数的结合 2.类 1.类的定义 2.类的实例化 3.继承 1.函数 1.函数的定义 def 函数名(输入参数): 文档字符串 函数体 …

Ubuntu20下C/C++编程开启TCP KeepAlive

1、在linux下&#xff0c;测试tcp保活&#xff0c;可以使用tcp自带keepalive功能。 2、几个重要参数&#xff1a; tcp_keepalive_time&#xff1a;对端在指定时间内没有数据传输&#xff0c;则向对端发送一个keepalive packet&#xff0c;单位&#xff1a;秒 tcp_keep…

HTML静态网页成品作业(HTML+CSS+JS)——体育足球介绍设计制作(3个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;使用Javacsript代码实现图片轮播&#xff0c;共有3个页面。 二、作品…

借助ChatGPT提高编程效率指南

PS: ChatGPT无限次数&#xff0c;无需魔法&#xff0c;登录即可使用,网页打开下面 一、借助ChatGPT提高编程效率指南 随着计算机技术的飞速发展&#xff0c;编程已经成为了现代社会中一个非常重要的技能。对于许多人来说&#xff0c;编程不仅是一项工作技能&#xff0c;而且是…

HCIP —— BGP 路径属性 (上)

目录 BGP 路径属性 1.优选Preferred-Value属性值最大的路由 2.优选Local-preference 属性数值大的路由 3.本地始发的BGP路由优先于其他对等体处学习到的路由。 4..优选AS_PATH属性值最短的路由 BGP 路径属性 BGP的路由选路是存在优选规则的&#xff0c;下图为华为官网提供…

【MySQL探索之旅】MySQL数据表的增删查改(初阶)

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &…

Mac使用自动操作(Automator)发送文件到Android设备

需求场景 在Android开发调试的过程中&#xff0c;当需要把电脑上的文件传输到连接的Android设备时&#xff0c;通常的做法是通过adb push命令。那既然是通过命令操作&#xff0c;是否可以通过可视化的工具来操作呢&#xff1f;例如在Finder中&#xff0c;右击某一个文件或者目…
最新文章