访问者模式(十八)

相信自己,请一定要相信自己

上一章简单介绍了命令模式(十七), 如果没有看过, 请观看上一章

一. 访问者模式

引用 菜鸟教程里面访问者模式介绍: https://www.runoob.com/design-pattern/visitor-pattern.html

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。

通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。

根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作

一.一 介绍

意图: 主要将数据结构与数据操作分离。

主要解决: 稳定的数据结构和易变的操作耦合问题。

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

如何解决: 在被访问的类里面加一个对外提供接待访问者的接口。

关键代码: 在数据基础类里面有一个方法接受访问者,将自身引用传入访问者。

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

优点: 1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。

缺点: 1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

使用场景: 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

注意事项: 访问者可以对功能进行统一,可以做报表、UI、拦截器与过滤器。


组成角色具体关系
抽象访问者(Visitor)角色Action一个访问具体元素的接口,为每个具体元素类对应一个访问操作 visit() ,该操作中的参数类型标识了被访问的具体元素
具体访问者(ConcreteVisitor)角色FailAction, SuccessAction实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么
抽象元素(Element)角色Person声明一个包含接受操作 accept() 的接口,被接受的访问者对象作为 accept() 方法的参数
具体元素(ConcreteElement)角色Man WoMan实现抽象元素角色提供的 accept() 操作,其方法体通常都是 visitor.visit(this) ,另外具体元素中可能还包含本身业务逻辑的相关操作
对象结构(Object Structure)角色ObjectStructure是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法,通常由 List、Set、Map 等聚合类实现

image-20230615171102299

二. 访问者实例

二. 一 抽象访问者 Action

public abstract class Action {

    public abstract void getManResult (Man man);

    public abstract void getWomanResult(WoMan woMan);
}

二.二 具体访问者实现

二.二.一 差

@Slf4j
public class FailAction extends Action{

    @Override
    public void getManResult(Man man) {
        log.info("男生{}评价差",man.getName());
    }

    @Override
    public void getWomanResult(WoMan woMan) {
        log.info("女生评价{}差",woMan.getName());
    }
}

二.二.二 优

@Slf4j
public class SuccessAction extends Action{

    @Override
    public void getManResult(Man man) {
        log.info("男生{}评价优秀",man.getName());
    }

    @Override
    public void getWomanResult(WoMan woMan) {
        log.info("女生评价{}优秀",woMan.getName());
    }
}

二.二.三 待评价

@Slf4j
public class WaitAction extends Action{

    @Override
    public void getManResult(Man man) {
        log.info("男生{} 待评价",man.getName());
    }

    @Override
    public void getWomanResult(WoMan woMan) {
        log.info("女生{}待评价",woMan.getName());
    }
}

二.三 抽象元素 Person

@EqualsAndHashCode(of = {"name"})
public abstract class Person {
    private String name;

    public abstract  void accept(Action action);

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

二.四 具体元素

二.四.一 男人

public class Man extends Person{
    public Man (String name) {
        super.setName(name);
    }
    @Override
    public void accept(Action action) {
        action.getManResult(this);
    }
}

二.四.二 女人

public class WoMan extends Person{
    public WoMan (String name) {
       super.setName(name);
    }
    @Override
    public void accept(Action action) {
        action.getWomanResult(this);
    }
}

二.五 对象结构 ObjectStructure

public class ObjectStructure {

    private List<Person> personList = new ArrayList<>();

    public void accept( Person person) {
        personList.add(person);
    }

    public void remove(Person person) {
        personList.remove(person);
    }

    public void display (Action action) {
        for (Person person : personList) {
            person.accept(action);
        }
    }
}

二.六 测试

@Test
    public void oneTest() {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.accept(new Man("张三"));
        // 是成功的
        objectStructure.display(new SuccessAction());

        objectStructure.remove(new Man("张三"));
        objectStructure.accept(new Man("李四"));

        objectStructure.display(new FailAction());

        objectStructure.remove(new Man("李四"));
        objectStructure.accept(new WoMan("王二"));
        objectStructure.accept(new WoMan("麻子"));

        objectStructure.display(new WaitAction());

    }

image-20230615171718905

优点:

  1. 访问者模式符合单一职责原则、让程序具有优秀的扩展性、灵活性非常高

  2. 访问者模式可以对功能进行统一,可以做报表、UI、拦截器与过滤器,适用于数据结构相对稳定的系统

缺点:

  1. 具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的, 这样造 成了具体元素变更比较困难

  2. 违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素

  3. 因此,如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的.


本章节的代码放置在 github 上:


https://github.com/yuejianli/DesignPattern/tree/develop/Visitor


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

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

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

相关文章

K8s in Action 阅读笔记——【14】Securing cluster nodes and the network

K8s in Action 阅读笔记——【14】Securing cluster nodes and the network 迄今为止&#xff0c;创建了 Pod 而不考虑它们允许消耗多少 CPU 和内存。但是&#xff0c;正如将在本章中看到的那样&#xff0c;设置 Pod 预期消耗和允许消耗的最大数量是任何 Pod 定义的重要部分。…

基于Flask+Bootstrap+机器学习的世界杯比赛预测系统

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

南京贸易企业增值税居高不下,该如何解决?

南京贸易企业增值税居高不下&#xff0c;该如何解决&#xff1f; 《税筹顾问》专注于园区招商&#xff0c;您的贴身节税小能手&#xff0c;合理合规节税&#xff01; 南京作为省会城市&#xff0c;近年来由于芯片、生物医药等产业的发展而跻身前十&#xff0c;随着它在教育、军…

C语言基础 位域

C语言基础&#xff1a;位域 主题&#xff1a;位域&#xff08;bit-field&#xff09; 关键字&#xff1a;位域 冒号 结构体 存储空间 参考链接&#xff1a;C语言中文网&#xff1a;位域 、C菜鸟工具&#xff08;在线编译器&#xff09;、位域知乎问答 注&#xff1a;以下内容中…

redis五种数据类型具体时候的底层编码

redis随着值的类型不同&#xff0c;其在底层编码类型会不相同。目前现有的编码格式有 #define OBJ_ENCODING_RAW 0 /* Raw representation */ #define OBJ_ENCODING_INT 1 /* Encoded as integer */ #define OBJ_ENCODING_HT 2 /* Encoded as hash table */ #def…

2023年打印机电商市场数据分析

近年来&#xff0c;伴随自动化办公及在线教育等场景的常态化&#xff0c;文件或学习资料等的打印需求不断增长&#xff0c;这也使得打印机需求暴增&#xff0c;打印机市场的市场规模也越来越大。 根据鲸参谋电商平台的相关数据显示&#xff0c;今年1月份至4月份&#xff0c;打印…

Unity UGUI1——基础组件概述

一、UGUI 介绍 ​ UGUI 是 Unity 引擎内自带的 UI 系统&#xff0c;官方称之为&#xff1a;Unity UI ​ 是目前 Unity 商业游戏开发中使用最广泛的 UI 系统开发解决方案 ​ 它是基于 Unity 游戏对象的 UI 系统&#xff0c;只能用来做游戏 UI 功能 ​ 不能用于开发 Unity 编…

简单的TCP网络程序·单进程(后端服务器)

目录 文件1&#xff1a;tcpServer.cc 文件2&#xff1a;tcpServer.hpp 1.提出日志概念 -- 在后续完善 日志格式 -- 暂定简单的打印功能 2.创建套接字 SOCK_STREAM -- socket参数 3.bind自己的套接字 4.设置socket 为监听状态 * 新接口1&#xff1a;listen 函数1&…

linux服务器上,docker安装nginx

如果出现 Using default tag: latest Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/create?fromImagenginx&taglatest": dial unix /va…

Python 中常用的数据类型及相关操作详解

文章目录 列表&#xff08;Lists&#xff09;创建列表访问列表元素添加元素到列表删除列表元素切片&#xff08;Slicing&#xff09;其他常用操作 元组&#xff08;Tuples&#xff09;创建元组访问元组元素元组长度其他常用操作 字符串&#xff08;Strings&#xff09;创建字符…

Three.js--》实现图片转3D效果展示

目录 项目搭建 初始化three.js基础代码 加载图片纹理 设置着色器 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还是借助框架书写th…

【Qt】Ubuntu安装GCC9.3.0版本的Qt5.15.5

目录 一、安装GCC9.3.0 1.下载GCC9.3.0源码 2.获取依赖项的包 3.生成Makefile文件 4.编译并安装 5.生成软链接 6. 查看GCC版本 二、安装Qt 1.下载Qt安装包 2.创建Qt项目并运行 一、安装GCC9.3.0 1.下载GCC9.3.0源码 https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3…

excel爬虫相关学习1:简单的excel爬虫

目录 1 什么是excel 爬虫 2 EXCEL爬虫 2.1 excel 爬虫的入口 2.2 需要配置的信息 2.2.1 如何获得 ua信息 2.3 获取的信息 2.3.1 获取信息的基本内容 2.3.2 获取过程 2.3.3 我们只用关注“表视图 ” 即可 2.4 EXCEL获得的爬虫数据 加载到excel里 2.5 数据到了excel表后…

Three.js--》实现3d汽车模型展览搭建

目录 项目搭建 初始化three.js基础代码 添加汽车模型展示 动态修改汽车模型 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还是借助…

flink主要组件及高可用配置

背景 flink不论运行在哪种环境&#xff0c;例如Yarn&#xff0c;Mesos&#xff0c;Kebernute以及独立集群&#xff0c;每个应用都会包含重要的几个组件&#xff0c;本文就来讲述下flink的主要组件以及如何实现flink的高可用配置 flink主要组件 如图所示&#xff0c;flink主要…

Java实训日志02

文章目录 八、项目开发实现步骤&#xff08;二&#xff09;创建项目1、创建Java项目2、创建目录&#xff0c;添加素材&#xff08;1&#xff09;创建help目录添加帮助文档&#xff08;2&#xff09;创建images目录添加图像素材&#xff08;3&#xff09;创建lib目录添加数据库驱…

Dockerfile创建镜像

一、Docker镜像的创建 创建镜像有三种方法&#xff0c;分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 1.1 基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it centos:7 /bin/bash …

设计模式之工厂方法模式笔记

设计模式之工厂方法模式笔记 说明Factory Method(工厂方法)目录UML抽象工厂示例类图咖啡抽象类美式咖啡类拿铁咖啡类 咖啡工厂接口美式咖啡工厂类拿铁咖啡工厂类 咖啡店类测试类 说明 记录下学习设计模式-工厂方法模式的写法。 Factory Method(工厂方法) 意图:定义一个用于创…

主从架构lua脚本-Redis(四)

上篇文章介绍了rdb、aof持久化。 持久化RDB/AOF-Redis&#xff08;三&#xff09;https://blog.csdn.net/ke1ying/article/details/131148269 redis数据备份策略 写job每小时copy一份到其他目录。目录里可以保留最近一个月数据。把目录日志保存到其他服务器&#xff0c;防止机…

专业的知识图谱应用门槛正在被不断降低

前⾔ 知识图谱&#xff08;knowledge graph&#xff09;⼀度被专家称为“AI皇冠上的明珠”&#xff0c;因为知识图谱技术是⼈⼯智能技术⽅向中的重要⼀环。它不仅可以为其他⼈⼯智能应⽤提供⽀持&#xff0c;如⾃然语⾔处理、推荐系统等&#xff0c;更可以帮助⼈⼯智能系统⾃主…