蘇阿細 - 访问者模式
type: channel
link: https://www.wangchouchou.com/tag/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F/
items: 行为型模式-访问者模式

行为型模式-访问者模式
type: item
date: 2022-09-25T02:24:00+00:00
description: （1）概述封装一些作用于某种数据结构中的各元素的操作，它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作（2）结构抽象访问者角色：定义对每一个元素访问的行为，它的参数就是可以访问的元素（它的方法个数理论上来说与元素个数相等）具体访问者角色：给出对每一个元素类访问时所产生的具体行为抽象元素角色：定义接受访问者的方法（即每一个元素都可以被访问者访问）具体元素角色：提供接受访问方法的具体实现，而这个具体的实现，通常情况下是使用访问者提供的访问该元素类的方法对象结构角色：一个具有容器性质或复合对象特性的类，它含有一组元素，且可以迭代这些元素，供访问者访问（3）案例以宠物喂食为例访问者角色：给宠物喂食的人具体访问者角色：宠物主人、其他人等抽象元素角色：动物抽象类具体元素角色：宠物狗、宠物猫结构对象角色：主人家抽象访问者角色public interface Person { /** * 喂猫 * * @param cat 猫 */ void feed(Cat cat); /** * 喂狗 * * @param dog 狗 */ void feed(Dog dog); }具体访问者public class Owner implements Person { @Override public void feed(Cat cat) { System.out.println("主人喂猫"); } @Override public void feed(Dog dog) { System.out.println("主人喂狗"); } } public class Someone implements Person { @Override public void feed(Cat cat) { System.out.println("客人喂猫"); } @Override public void feed(Dog dog) { System.out.println("客人喂狗"); } }抽象元素角色public interface Animal { /** * 接受访问者访问 * * @param person 访问者 */ void accept(Person person); }具体元素角色public class Dog implements Animal { @Override public void accept(Person person) { person.feed(this); System.out.println("喂狗吃狗粮"); } } public class Cat implements Animal { @Override public void accept(Person person) { person.feed(this); System.out.println("喂猫吃猫粮"); } }结构对象角色public class Home { private List<Animal> nodeList = new ArrayList<>(); void add(Animal animal) { nodeList.add(animal); } void action(Person person) { //访问者访问每一个元素 for (Animal animal : nodeList) { animal.accept(person); } } }Clientpublic class Client { public static void main(String[] args) { //创建Home Home home = new Home(); //添加元素 home.add(new Dog()); home.add(new Cat()); //创建主人对象 Owner owner = new Owner(); //主人喂宠物 home.action(owner); } }（4）优缺点扩展性好：在不修改对象结构中的元素的情况下，为对象结构中的元素添加新的功能复用性好：通过访问者来定义整个对象结构的通用的功能，从而提高代码复用分离无关行为：通过访问者来分离无关的行为，把相关的行为封装在一起，构成一个访问者，使得每一个访问者的功能都比较单一对象结构变化困难：每增加一个新的元素类，都要在每一个具体访问者中增加相应的具体操作，违背了开闭原则违反了依赖倒置原则：访问者依赖具体类，而不依赖抽象类（5）使用场景对象结构稳定，但其操作算法经常变更时对象结构中对象需要提供多种不同且不相关的操作，而且要避免让这些操作的变化影响对象的结构时（6）扩展访问者模式使用了双分派技术1. 分派变量被声明时的类型叫做变量的静态类型，变量所引用…