【Java设计模式】二十一、访问者模式

文章目录

  • 1、访问者模式
  • 2、案例:宠物喂食
  • 3、总结

1、访问者模式

封装一些作用于某种容器中各个元素的操作。相关角色:

  • 抽象访问者:定义了对每一类元素访问的行为。方法个数等于具体元素类的个数,方法形参是可访问的元素。
  • 具体访问者:实现类,重写定义对每一类元素访问时所产生的具体行为
  • 抽象元素类:定义一个接收访问者的方法,方法形参为抽象访问者
  • 具体元素类:实现类,重写元素类在接受访问者访问时对应的具体行为
  • 对象结构角色:一个容器,包含一组元素,可迭代元素,让访问者去访问

2、案例:宠物喂食

给宠物喂食,宠物可以是猫、狗,喂食的人可以是主人、其他人。角色对应:

  • 访问者角色:给宠物喂食的人(两个具体元素,两个feed方法)
  • 具体访问者角色:主人、其他人
  • 抽象元素角色:动物抽象类
  • 具体元素角色:宠物狗、宠物猫
  • 结构对象角色:主人家

在这里插入图片描述
创建抽象访问者接口:

public interface Person {void feed(Cat cat);void feed(Dog dog);
}

创建不同的具体访问者角色(主人和其他人),都需要实现 Person接口:

public class Owner implements Person {@Overridepublic void feed(Cat cat) {System.out.println("主人喂食猫");}@Overridepublic void feed(Dog dog) {System.out.println("主人喂食狗");}
}
public class Someone implements Person {@Overridepublic void feed(Cat cat) {System.out.println("其他人喂食猫");}@Overridepublic void feed(Dog dog) {System.out.println("其他人喂食狗");}
}

定义抽象元素角色类 – 宠物,里面有一个接受访问者访问的方法,形参为访问者角色类

public interface Animal {void accept(Person person);
}

定义实现Animal接口的 具体元素角色类:宠物狗和宠物猫

public class Dog implements Animal {@Overridepublic void accept(Person person) {person.feed(this);System.out.println("好好吃,汪汪汪!!!");}
}
public class Cat implements Animal {@Overridepublic void accept(Person person) {person.feed(this);System.out.println("好好吃,喵喵喵!!!");}
}

定义对象结构类,此案例中就是主人的家。声明一个集合,用来存储元素对象

public class Home {private List<Animal> nodeList = new ArrayList<Animal>();public void action(Person person) {for (Animal node : nodeList) {node.accept(person);}}//添加操作public void add(Animal animal) {nodeList.add(animal);}
}

测试类:

public class Client {public static void main(String[] args) {Home home = new Home();home.add(new Dog());home.add(new Cat());Owner owner = new Owner();home.action(owner);//Someone someone = new Someone();//home.action(someone);}
}

在这里插入图片描述

3、总结

优点:

  • 扩展性好

    在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。

  • 复用性好

    通过访问者来定义整个对象结构通用的功能,从而提高复用程度。

  • 分离无关行为

    通过访问者来分离无关的行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一。

缺点:

  • 对象结构变化很困难

    在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”。

  • 违反了依赖倒置原则

    访问者模式依赖了具体类,而没有依赖抽象类。

使用场景:

  • 对象结构相对稳定,但其操作算法经常变化的程序。

  • 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。

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

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

相关文章

固态硬盘有缓存和没缓存有什么区别

固态硬盘&#xff08;SSD&#xff09;已经成为现代计算机的重要组成部分&#xff0c;它们提供了比传统机械硬盘更快的读写速度&#xff0c;从而显著提升了操作系统的运行速度和应用程序的加载效率。 其中&#xff0c;缓存&#xff08;Cache&#xff09;是固态硬盘中一个重要的…

留学生课设|R语言|研究方法课设

目录 INSTRUCTIONS Question 1. Understanding Quantitative Research Question 2. Inputting data into Jamovi and creating variables (using the dataset) Question 3. Outliers Question 4. Tests for mean difference Question 5. Correlation Analysis INSTRUCTIO…

idea如何使用,从激活开始

idea到期后激活使用 如何使用 点击阅读 idea分享

边缘计算与物联网的核心 —— 低功耗芯片

一、低功耗芯片 在边缘计算与物联网&#xff08;IoT&#xff09;中&#xff0c;低功耗芯片扮演了至关重要的角色&#xff0c;主要体现在以下几个方面&#xff1a; 延长设备寿命&#xff1a;物联网设备通常需要部署在难以更换电池或不方便进行频繁维护的环境中&#xff0c;比如…

【FPGA】DDR3学习笔记(二)丨从SDRAM到DDR3的IP核设计

本篇文章包含的内容 一、DDR SDRAM1.1 基本概述1.2 工作时序&#xff08;以读取为例&#xff09; 二、DDR2 SDRAM2.1 基本概述2.2 工作时序 三、DDR3 SDRAM3.1 基本概述3.2 硬件设计3.3 读写时序3.4 MIG IP核设计3.5 读写代码设计 开发板&#xff1a;正点原子的达芬奇开发板&am…

PlantUML Integration 编写短信服务类图

PlantUML Integration 写一个类图&#xff0c;主要功能为 1、编写一个serviceSms短信服务类&#xff1b; 2、需要用到短信的地方统一调用基建层的服务即可&#xff1b; 3、可以随意切换、增加短信厂商&#xff0c;不需要更改场景代码&#xff0c;只需要更改application.yml 里面…

【OpenCV】手写字符分割

OpenCV 是一个开源的计算机视觉&#xff08;Computer Vision&#xff09;与机器学习软件库&#xff0c;提供了多种图像处理算法与接口。在 OCR 技术中&#xff0c;字符分割用于提取图像中的文字信息&#xff0c;可以应用于车牌识别、身份证识别、文档扫描等场景。本文主要记录如…

【Flutter学习笔记】9.6 动画切换组件(AnimatedSwitcher)

参考资料&#xff1a;《Flutter实战第二版》9.6 动画切换组件&#xff08;AnimatedSwitcher&#xff09; 9.6.1 AnimatedSwitcher AnimatedSwitcher 可以同时对其新、旧子元素添加显示、隐藏动画&#xff0c;在需要切换新旧元素的场景广泛使用。也就是说在AnimatedSwitcher的子…

Java操作Sql语句 出现迭代死循环 (Bug排查)

目录 1. 问题所示2. 原理分析3. 解决方法4. 彩蛋1. 问题所示 Java执行Sql语句来查询一些数据的时候 虽说数据量很大,但是查询过程中一直迭代查询 截图如下所示: 2. 原理分析 至于迭代死循环,可能是不满足的条件也进入查询(本身我的数据量就很大) 主要可能引起的两个原…

Python数学建模-2.3函数(下)

2.3.2模块的导入与使用 模块在Python中是一个包含Python定义和语句的文件&#xff0c;通常用来组织代码&#xff0c;使得代码更易于管理和复用。下面&#xff0c;我将详细讲解Python函数中模块的使用知识。 1. 模块的导入 在Python中&#xff0c;你可以使用import语句来导入…

【新书推荐】29.1 32位汇编基本概念

第二十九章 32处理器体系结构 这一章我们将讲述32处理器体系结构。包括32位计算机的一些基本概念&#xff0c;32位处理器&#xff0c;程序加载执行的过程&#xff0c;32位计算机的硬件组成和输入输出系统。 29.1 基本概念 本节内容&#xff1a; ■实模式与保护模式 ■操作系…

【华为 ICT HCIA eNSP 习题汇总】——题目集16

1、下面哪一个最适合使用室内分布方式部署 WLAN&#xff1f; A、运动场 B、办公室 C、高校单排宿舍 D、广场 考点&#xff1a;无线局域网 解析&#xff1a;&#xff08;C&#xff09; 室内分布方式部署 WLAN 一般适用于需要大面积、高密度、高质量无线覆盖的场所&#xff0c;从…