设计模式-行为型模式-访问者模式

        访问者模式难以实现,且应用该模式可能会导致代码可读性变差,可维护性变差,除非必要,不建议使用;

1.访问者模式定义

        允许在运行时将一个或多个操作应用于一组对象,将操作与对象结构分离;

        访问者模式主要解决的是数据与算法的耦合问题,尤其是在数据结构比较稳定,而算法多变的情况下,为了不污染数据本身,访问者会将多种算法独立归档,并在访问数据时根据数据类型自动切换到对应的算法,实现数据的自动响应机制,并确保算法的自由扩展;

1.1 访问者模式优缺点

优点

  • 扩展性好,在不修改对象结构中元素的情况下,为对象结构中的元素添加新的功能;
  • 复用性好,通过访问者来定义整个对象结构通用的功能,从而提高复用程度;
  • 分离无关行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一;

缺点

  • 对象结构变化很困难,在访问者模式中,没增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了开闭原则;
  • 违反了依赖倒置原则,访问者模式依赖了具体类,而没有依赖抽象类;

1.2 访问者模式的使用场景

  • 当对象的数据结构相对稳定,而操作却经常变化的时候。 比如,上面例子中路由器本身的内部构造(也就是数据结构)不会怎么变化,但是在不同操作系统下的操作可能会经常变化,比如,发送数据、接收数据等。
  • 需要将数据结构与不常用的操作进行分离的时候。 比如,扫描文件内容这个动作通常不是文件常用的操作,但是对于文件夹和文件来说,和数据结构本身没有太大关系(树形结构的遍历操作),扫描是一个额外的动作,如果给每个文件都添加一个扫描操作会太过于重复,这时采用访问者模式是非常合适的,能够很好分离文件自身的遍历操作和外部的扫描操作。
  • 需要在运行时动态决定使用哪些对象和方法的时候。 比如,对于监控系统来说,很多时候需要监控运行时的程序状态,但大多数时候又无法预知对象编译时的状态和参数,这时使用访问者模式就可以动态增加监控行为。

2.访问者模式原理

  • 抽象访问者(Visitor):可以是接口或抽象类,定义了一系列操作方法,用来处理所有数据元素,通常为同名的访问方法,并以数据元素作为入参来确定哪个重载方法被调用;
  • 具体访问者(ConcreteVisitor):实现了抽象访问者,可以有多个,每个访问者都需要实现所有数据元素类型的访问重载发方法;
  • 抽象元素类(Element):被访问的数据元素接口,定义了一个接受访问者的方法,每个元素都要可以被访问者访问;
  • 具体元素类(ConcreteElement):具体数据元素实现类,提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法;
  • 对象结构类(ObjectStructure):包含所有可能被访问的数据对象的容器,可以提供数据对象的迭代功能,可以是任意类型的数据结构;
  • 客户端:使用容器并初始化其中各类数据元素,并选择合适的访问者处理容器中的所有数据对象;

3.访问者模式的实现

【实例】

        以超市购物为例,假设超市中的两类商品:糖果、酒水进行售卖。我们可以忽略每种商品的计价方法,因为最终结账时由收银员统一集中处理,在商品类中添加计价方法是不合理的设计;

【代码】

        访问者接口

public interface Visitor {public void visit(Wine wine);  //酒类重载方法public void visit(Candy candy);  //糖果重载方法
}

        接待者接口

public interface Acceptable {//接收所有的Visitor访问者的子类实现类public void accept(Visitor visitor);
}

        糖果类(酒类类似)

public class Candy extends Product implements Acceptable{public Candy(String name, LocalDate producedDate, double price) {super(name, producedDate, price);}@Overridepublic void accept(Visitor visitor) {//accept实现方法中调用访问者并将自己 "this" 传回。this是一个明确的身份,不存在任何泛型visitor.visit(this);}
}

        具体访问者——折扣计价访问者

public class DiscountVisitor implements Visitor {private LocalDate billDate;public DiscountVisitor(LocalDate billDate) {this.billDate = billDate;System.out.println("结算日期: " + billDate);}@Overridepublic void visit(Candy candy) {System.out.println("糖果: " + candy.getName());//获取产品生产天数long days = billDate.toEpochDay() - candy.getProducedDate().toEpochDay();if(days > 180){System.out.println("超过半年的糖果,请勿食用!");}else{double rate = 0.9;double discountPrice = candy.getPrice() * rate;System.out.println("糖果打折后的价格"+NumberFormat.getCurrencyInstance().format(discountPrice));}}@Overridepublic void visit(Wine wine) {System.out.println("酒类: " + wine.getName()+",无折扣价格!");System.out.println("原价: "+NumberFormat.getCurrencyInstance().format(wine.getPrice()));}
}

        客户端

public class Client {public static void main(String[] args) {//模拟添加多个商品的操作List<Acceptable> products = Arrays.asList(new Candy("金丝猴奶糖",LocalDate.of(2022,6,10),10.00),new Wine("衡水老白干",LocalDate.of(2020,6,10),100.00));Visitor visitor = new DiscountVisitor(LocalDate.of(2022,10,17));for (Acceptable product : products) {product.accept(visitor);}}
}

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

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

相关文章

【QT】Qt窗口

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;菜单栏设置&#x1f449;&#x1f3fb;QToolBar练习 &#x1f449;&#x1f3fb;QStausBar&#x1f449;&#x1f3fb;Q…

Debian11.9镜像基于jre1.8的Dockerfile

Debian11.9基于jre1.8的Dockerfile编写 # 使用Debian 11.9作为基础镜像 FROM debian:11.9 # 维护者信息&#xff08;建议使用LABEL而不是MAINTAINER&#xff0c;因为MAINTAINER已被弃用&#xff09; LABEL maintainer"caibingsen" # 创建一个目录来存放jre …

短剧市场快速发展,短剧APP成为了新的商业机遇

近几年&#xff0c;短剧作为一匹行业黑马&#xff0c;展现出了自身爆发式的发展态势&#xff0c;成功获得了大众关注&#xff0c;短剧的用户群体更是在持续上升&#xff0c;市场规模将达到500亿&#xff0c;发展前景巨大&#xff01; 目前&#xff0c;短剧都在小程序或者APP上…

多态(上)【C++】

文章目录 多态的概念多态的实现多态产生的条件什么是虚函数&#xff1f;虚函数的重写和协变重写协变 析构函数的重写为什么有必要要让析构函数构成重写&#xff1f; 多态的概念 C中的多态是面向对象编程&#xff08;OOP&#xff09;的一个核心特性&#xff0c;指的是同一个接口…

员工监控系统有哪些?6款员工屏幕监控系统大揭秘!(老板必看)

在企业管理中&#xff0c;如何提升员工工作效率并保障公司信息安全始终是管理者关注的焦点。 员工屏幕监控系统正是一个强大的工具&#xff0c;能够帮助企业了解员工的工作状态、管理工作进程&#xff0c;同时防止数据泄露。 今天小编就来为大家揭秘6款优秀的员工监控系统&…

JDK 家族成员 OpenKona 介绍

之前介绍过 JDK 的家族成员&#xff0c;具体戳这里。 本文将介绍 OpenKona(TencentKona)。 OpenKona 是基于 OpenJDK 研发的、支持国内技术生态和标准、开放源代码的 Java 开发工具包。OpenKona 兼容 JavaSE 规范&#xff0c;经过海量业务生产验证&#xff0c;生产环境开箱即用…

【linux笔记dpkg-buildpackage打包】把一个helloworld程序打包为deb包

说明 打包发布可以不用编译源代码安装&#xff0c;看起来是更方便的软件拷贝方式&#xff0c;下面是一个dpkg-buildpackage工具的最简打包过程实例 先建立一个helloworld程序 main.c #include <stdio.h>int main() {printf("Hello, World!\n");return 0; }…

长短期记忆网络和UKF的结合|Python代码例程

结合长短期记忆网络(LSTM)和无迹卡尔曼滤波器(UKF)的技术在机器人导航和状态估计中具有广泛的应用前景。 文章目录 结合LSTM和UKF的背景结合LSTM和UKF的优势应用实例研究现状Python代码示例结合LSTM和UKF的背景 长短期记忆网络(LSTM)是一种特殊的递归神经网络(RNN),…

电巢科技携Ecosmos元宇宙产品亮相第25届中国光博会

第25届中国国际光电博览会&#xff08;“CIOE中国光博会”&#xff09;今日在深圳国际会展中心盛大开幕。本届博览会以“光电引领未来&#xff0c;驱动应用创新”为主题&#xff0c;吸引了全球超过3700家优质光电企业参展&#xff0c;展示了光电产业的最新成果和前沿技术。 电…

动手学深度学习(pytorch土堆)-04torchvision中数据集的使用

CIFAR10 CIFAR-10 数据集由 10 个类的 60000 张 32x32 彩色图像组成&#xff0c;每个类有 6000 张图像。有 50000 张训练图像和 10000 张测试图像。 数据集分为 5 个训练批次和 1 个测试批次&#xff0c;每个批次有 10000 张图像。测试批次包含每个类中随机选择的 1000 张图像…

【基础算法总结】位运算

目录 一&#xff0c;常见位运算操作总结二&#xff0c;算法原理和代码实现191.位1的个数338.比特位计数461.汉明距离面试题01.01.判断字符是否唯一268.丢失的数字371.两整数之和136.只出现一次的数字137.只出现一次的数字II260.只出现一次的数据III面试题17.19.消失的两个数字 …

DIODE:超高分辨率室内室外数据集(猫脸码客 第186期)

亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 在计算…

抗菌肽;Parasin I;KGRGKQGGKVRAKAKTRSS;CAS号:219552-69-9

【Parasin I 简介】 Parasin I是一种抗菌肽&#xff0c;由19个氨基酸组成&#xff0c;最初从鲶鱼的皮肤粘液中分离得到。它具有广谱的抗菌活性&#xff0c;能够有效对抗革兰氏阳性菌和革兰氏阴性菌&#xff0c;包括一些对传统抗生素具有耐药性的菌株。 【中文名称】抗菌肽 Par…

USB摄像头视频流转RTSP流

一、VLC查看USB摄像头视频流原理&#xff1a; USB摄像头的工作原理与VLC播放其他视频文件类似&#xff0c;主要区别在于视频流的来源是实时捕获的&#xff0c;而不是预先录制的文件。如果使用VLC将USB摄像头的视频流作为RTSP服务器广播&#xff0c;需要进一步配置 二、VLC查看…

Java 设计模式-状态模式

目录 一. 概述 二. 主要角色 三. 代码示例 四. 优缺点 优点&#xff1a; 缺点&#xff1a; 五. 常见应用场景 一. 概述 状态模式是一种行为设计模式&#xff0c;它允许一个对象在其内部状态改变时改变它的行为。对象看起来好像修改了它的类。状态模式把所有的与一个特定…

新型 Vo1d 恶意软件曝光,超130万台安卓电视设备已中招

近日&#xff0c;有攻击者使用一种新的 Vo1d 后门恶意软件感染了 130 余万台安卓电视流媒体盒&#xff0c;使得攻击者能够完全控制这些设备。 Android TV是谷歌针对智能电视和流媒体设备推出的操作系统&#xff0c;为电视和远程导航提供了优化的用户界面&#xff0c;集成了谷歌…

MySQL--库的操作

文章目录 1.创建数据库2.创建数据库案例3.字符集和校验规则3.1默认字符集3.2默认校验规则3.3查看系统默认字符集以及校验规则3.4查看数据库支持的字符3.5查看数据库支持的字符集校验规则3.6校验规则对数据库的影响不区分大小写查询&#xff1a;排序结果&#xff1a;区分大小写查…

架构师白话分布式系统

对于分布式系统的定义,大致可以理解为如下的两个点 分布式系统从整体的体量来说,它内部是由很多的服务器、服务实例组成。所提供的用户服务是由一组相互独立运行的服务器来提供。对于用户来说,这个多服务器的系统就跟一个服务器一样,感觉不到每个单独的服务器实例的存在。从…

JSON串

JSON在客户端的使用 JSON 字符串的格式是基于键值对的数据结构&#xff0c;用于表示结构化数据。它遵循严格的语法规则&#xff0c;常用于前后端数据交互。 1. 基本结构 JSON 数据结构由两种主要元素构成&#xff1a; 对象&#xff08;Object&#xff09;&#xff1a;用花括…

小阿轩yx-Zabbix企业级分布式监控环境部署

小阿轩yx-Zabbix企业级分布式监控环境部署 前言 “运筹帷幄之中&#xff0c;决胜千里之外”监控在 IT 运维中占据着重要地位&#xff0c;按比例说占 30% 也不为过在监控系统开源软件中有很多可选择的工具&#xff0c;但是真正符合要求的、能够真正解决业务问题的监控系统软件…