访问者模式解读

news2024/12/23 1:10:19

目录

问题引进

访问者模式基本介绍

基本介绍

访问者模式的原理类图

对原理类图的说明 

访问者模式应用实例

思路分析和图解(类图)

代码实战 

 应用案例的小结

访问者模式的注意事项和细节

优点


问题引进

测评系统的需求
1) 将观众分为男人和女人,对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价(评价 有不同的种类,比如 成功、失败 等)

传统方式的问题分析
1) 如果系统比较小,还是 ok 的,但是考虑系统增加越来越多新的功能时,对代码改动较大,违反了 ocp 原则, 不利于维护
2) 扩展性不好,比如 增加了 新的人员类型,或者管理方法,都不好做
3) 引出我们会使用新的设计模式 – 访问者模式 

访问者模式基本介绍

基本介绍

1) 访问者模式(Visitor Pattern),封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
2) 主要将数据结构与数据操作分离,解决 数据结构和操作耦合性问题
3) 访问者模式的基本工作原理是:在被访问的类里面加一个对外提供接待访问者的接口

4) 访问者模式主要应用场景是:需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联),同时需要避免让这些操作"污染"这些对象的类,可以选用访问者模式解决

访问者模式的原理类图

对原理类图的说明 

1) Visitor 是抽象访问者,为该对象结构中的 ConcreteElement 的每一个类声明一个 visit 操作
2) ConcreteVisitor :是一个具体的访问值 实现每个有 Visitor 声明的操作,是每个操作实现的部分.
3) ObjectStructure 能枚举它的元素, 可以提供一个高层的接口,用来允许访问者访问元素
4) Element 定义一个 accept 方法,接收一个访问者对象
5) ConcreteElement 为具体元素,实现了 accept 方法

访问者模式应用实例

应用实例要求
1) 将人分为男人和女人,对歌手进行测评,当看完某个歌手表演后,得到他们对该歌手不同的评价(评价 有不同的种类,比如 成功、失败 等),请使用访问者模式来说实现

思路分析和图解(类图)

代码实战 

Action  

public abstract class Action {
    //男性的测评
    public abstract  void  getManResult(Man man);

    //女性的测评
    public abstract  void getWomanResult(Woman woman);
}

 Person 

public abstract class Person {
    //提供一个方法,让访问者可以访问
    public abstract void accept(Action action);
}

 Man 

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

 Woman  

public class Woman  extends  Person{
    @Override
    public void accept(Action action) {
        action.getWomanResult(this);
    }
}

 Fail 

public class Fail extends Action {
    @Override
    public void getManResult(Man man) {
        System.out.println(" 男人给的评价该歌手失败 !");
    }

    @Override
    public void getWomanResult(Woman woman) {
        System.out.println(" 女人给的评价该歌手失败 !");
    }
}

  Success 

public class Success extends  Action{
    @Override
    public void getManResult(Man man) {
        System.out.println(" 男人给的评价该歌手很成功 !");
    }

    @Override
    public void getWomanResult(Woman woman) {
        System.out.println(" 女人给的评价该歌手很成功 !");
    }
}

ObjectStructure 

public class ObjectStructure {
    //维护了一个集合
    private List<Person> persons = new LinkedList<>();

    //增加到 list
    public void attach(Person p) {
        persons.add(p);
    }
    //移除
    public void detach(Person p) {
        persons.remove(p);
    }
    //显示测评情况
    public void display(Action action) {
        for (Person p : persons) {
            p.accept(action);
        }
    }
}

 Client 

public class Client {
    public static void main(String[] args) {
        //创建 ObjectStructure
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.attach(new Man());
        objectStructure.attach(new Woman());
        //成功
        Success success = new Success();
        objectStructure.display(success);
        System.out.println("===============");
        Fail fail = new Fail();
        objectStructure.display(fail);

    }
}

 

 应用案例的小结

双分派,所谓双分派是指不管类怎么变化,我们都能找到期望的方法运行。双分派意味着得到执行的操作取决于请求的种类和两个接收者的类型

以上述实例为例,假设我们要添加一个 Wait 的状态类,考察 Man 类和 Woman 类的反应,由于使用了双分派,只需增加一个 Action 子类即可在客户端调用即可,不需要改动任何其他类的代码。

  • 单分派

依据单个宗量进行方法的选择就叫单分派,Java 动态分派只根据方法的接收者一个宗量进行分配,所以其是单分派

访问者模式的注意事项和细节

优点

1) 访问者模式符合单一职责原则、让程序具有优秀的扩展性、灵活性非常高
2) 访问者模式可以对功能进行统一,可以做报表、UI、拦截器与过滤器,适用于数据结构相对稳定的系统

缺点

1) 具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的, 这样造成了具体元素变更比较困难
2) 违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素
3) 因此,如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的 

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

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

相关文章

FPGA基于XDMA实现PCIE X8通信方案测速 提供工程源码和QT上位机程序和技术支持

目录 1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案5、vivado工程详解6、驱动安装7、QT上位机软件8、上板调试验证9、福利&#xff1a;工程代码的获取 1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xff0c;比起 PC…

Ceph手动部署(开发版本)

手动部署 监视器引导管理器守护程序配置添加 OSD 简写形式长格式添加 MDS总结在 FreeBSD 上手动部署 FreeBSD 上的 Disklayout 配置监视器引导添加 OSD 长格式添加 MDS总结 手动部署 所有 Ceph 集群至少需要一个显示器&#xff0c;并且至少需要与 存储在群集上的对象的副本…

Hacked某安汽车车机系统

很久之前尝试对某安汽车的车机系统进行渗透测试&#xff0c;但是却卡在入口无法进入&#xff0c;尝试暴力破解但是字典不够强大&#xff0c;没能成功。前段时间看到了绿盟科技博客的《新型车机&#xff0c;如何攻防&#xff1f;》感觉有点熟悉&#xff0c;再次探索发现可以获得…

京东商品评论数据爬虫,包含对数据的采集、清洗、可视化、分析等过程,作为数据库课程。

感谢大家的star和fork&#xff0c;为了感谢大家的关注&#xff0c;特意对代码进行了优化&#xff0c;对最新的url格式进行了更新&#xff0c;减少了一些冗余的参数&#xff0c;希望能够帮助大家入门爬虫&#xff0c;已经爬好的京东的商品评论数据已经存储在data目录下&#xff…

软件测试标准GB/T 25000.51-2016中的八大软件质量特性

GB/T25000标准由下图所示的21个部分组成&#xff0c;其中GB/T 25000.10和GB/T 25000.51是建立软件测试技术体系可以参考的部分&#xff0c;GB/T 25000.51尤为重要。 GB/T 25000标准总标题&#xff08;21个部分&#xff09; GB/T 25000.51标准pdf封面 GB/T 25000.51-2016 《系统…

现在有t1,t2,t3三个线程,实现t1,t2线程同步执行,然后再执行t3线程,使用Java实现该程序

目录 1、利用CountDownLatch 2、利用Future 最近在面试的时候&#xff0c;经常遇到这个题目&#xff0c;首先从题目上看&#xff0c;就知道考察的是多线程方面知识&#xff0c;我第一次看到这个题目的时候&#xff0c;就想到了使用CountDownLatch这个计数器来实现&#xff0c…

AUTOSAR网络管理

功能说明 目前车辆上ECU的数目越来越多&#xff0c;不同功能的ECU对电源有不同的要求&#xff0c;在点火钥匙打到OFF档&#xff08;KL15停止供电&#xff09;之后&#xff0c;有的ECU&#xff08;如座椅模块&#xff09;允许直接断电&#xff0c;有的ECU&#xff08;如空调模块…

浅谈操作系统OS与计算机软硬件体系结构,自顶贯穿性与行为回归硬件性

操作系统OS与计算机软硬件体系结构 使计算机更好用! 这是操作系统的根本要义!! 操作系统这个概念基本上以后会讲一路的&#xff0c;今天的话就基本上讲一下轻量化的概念。所以操作系统到底是什么&#xff1f;操作系统首先是软件&#xff0c;那它是一款什么软件呢&#xff1f…

Java读取文件方式

IO流读取 文本内容 按行读取文件内容 指定编码格式&#xff08;推荐&#xff09; public static void main(String[] args) throws UnsupportedEncodingException {read("D:\\test.txt");}public static void read(String path) {BufferedReader reader null;try …

Spring Security 01 整体架构

目录 认证 AuthenticationManager ProviderManager AuthenticationProvider Authentication SecurityContextHolder 授权 AccessDecisionManager AccessDecisionVoter RoleVoter AuthenticatedVoter Custom Voters ConfigAttribute 在SpringSecurity的架构中&…

Linux如何使用宝塔面板搭建网站和内网穿透实现公网访问

文章目录 前言1. 环境安装2. 安装cpolar内网穿透3. 内网穿透4. 固定http地址5. 配置二级子域名6. 创建一个测试页面 转载自远程内网穿透的文章&#xff1a;Linux使用宝塔面板搭建网站&#xff0c;并内网穿透实现公网访问 前言 宝塔面板作为简单好用的服务器运维管理面板&#…

Flink从入门到精通之-06Flink 中的时间和窗口

Flink从入门到精通之-06Flink 中的时间和窗口 我们已经了解了基本 API 的用法&#xff0c;熟悉了 DataStream 进行简单转换、聚合的一些操作。除此之外&#xff0c;Flink 还提供了丰富的转换算子&#xff0c;可以用于更加复杂的处理场景。 在流数据处理应用中&#xff0c;一个…

NM储存卡数据丢失怎么办?四招数据恢复宝典

NM卡像其他类型的存储设备一样&#xff0c;也有可能因为各种原因导致数据丢失&#xff0c;比如误删除、格式化、病毒感染等。因此&#xff0c;在使用NM卡时&#xff0c;仍需注意数据备份和安全性&#xff0c;以避免面临重要数据丢失风险。如果不幸发生了数据丢失&#xff0c;应…

python中unexpected indent报错的解决办法

python中unexpected indent报错的解决办法 在我们初步学习pyton的时候&#xff0c;由于对python语言的学习掌握不充分&#xff0c;则会导致所编写的代码&#xff0c;运行时候报错。比如&#xff0c;容易报错的unexpected indent问题&#xff0c;下面举例说明问题。 1.举例&am…

Linux虚拟机中安装jdk的两种方法:

方法一&#xff1a;手动安装 1. 使用FinalShell自带的上传工具将jdk的二进制发布包上传到Linux 上传位置如图&#xff08;底栏可以在图中的向下箭头位置自行打开与关闭&#xff09;&#xff1a; 注&#xff1a;默认上传地址为图片左侧的工作地址 2. 解压安装包&#xff0c;…

在vue2中用vue-echarts和v-charts绘制百度地图定制散点图

一、在vue-echarts中定制百度地图 效果 准备 安装依赖 echarts vue-echarts npm i echarts vue-echarts 在main.js中引入 import ECharts from “echarts” import VueECharts from “vue-echarts” Vue.prototype.$echarts ECharts Vue.component(“v-chart”, VueECharts…

SAS学习第4章:t检验

前话&#xff1a;分析试验数据的差异&#xff0c;一般都会假设样本值之间或者样本与标准值之间无差异&#xff0c;根据不同方法计算得出的t值、q值、F值等等&#xff0c;均表示两者之间的差异程度&#xff0c;值越大&#xff0c;两者差异越大&#xff0c;该假设越不成立&#x…

全网最全的AI绘画提示词网站,看这一篇就够了!

要说2023年什么最火&#xff0c;绝对是以ChatGPT为代表的AI工具了&#xff0c;特别是AI绘画&#xff0c;而用好AI的关键&#xff0c;就是要学会使用关键词&#xff0c;也叫提示词&#xff0c;提示词是AI绘画的核心&#xff0c;本次就给大家分享几个AI绘画关键词网站&#xff0c…

大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端

前言&#xff1a;苟有恒&#xff0c;何必三更眠五更起&#xff1b;最无益&#xff0c;莫过一日曝十日寒。 前言 之前一直想写个 WanAndroid 项目来巩固自己对 KotlinJetpack协程 等知识的学习&#xff0c;但是一直没有时间。这里重新行动起来&#xff0c;从项目搭建到完成前前…

奇异值分解SVD

概念 奇异值分解&#xff08;singular value decomposition&#xff09;是线性代数中一种重要的矩阵分解。奇异值分解在某些方面与对称矩阵或厄密矩阵基于特征向量的对角化类似。然而这两种矩阵分解尽管有其相关性&#xff0c;但还是有明显的不同。对称矩阵特征向量分解的基础…