设计模式(23):访问者模式

定义

  • 表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变元素的类的前提下定义作用与这些元素的新操作。

模式动机

  • 对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其访问方式也有所不同。

访问者模式角色

  • 抽象访问者: 一般通过visit方法声明可以访问哪写元素;
  • 具体访问者: 实现抽象访问者。访问元素的内容;
  • 抽象元素: 需要被访问的对象。一般有一个accept方法接受访问者方法;
  • 具体元素: 实现了抽象元素。在accept方法中调用访问者的visit方法;

开发中常见的场景

  • XML文挡解释器设计
  • 编译器的设计
  • 复杂集合对象的处理

总结

  • 访问者模式是GOF23种设计模式中最复杂的一种设计模式,一般在工作中不会使用访问者设计模式,也尽量不要使用访问者设计模式;如果用到了访问者设计模式,那就是必须要使用访问者设计模式啦。

代码实现

  • 抽象访问者
java 复制代码
/**
 * 抽象访问者
 */
public interface Visitor {

	void visit(ManElement manElement);
	
	void visit(WomanElement womanElement);
}
  • 具体访问者
java 复制代码
/**
 * 具体访问者NameVisitor
 */
public class NameVisitor implements Visitor {
	@Override
	public void visit(ManElement manElement) {
		System.out.println("名称:"+manElement.getName());
	}
	@Override
	public void visit(WomanElement womanElement) {
		System.out.println("名称:"+womanElement.getName());
	}
}
/**
 * 具体访问者GenderVisitor
 */
public class GenderVisitor implements Visitor {
	@Override
	public void visit(ManElement manElement) {
		System.out.println("性别:男");
	}
	@Override
	public void visit(WomanElement womanElement) {
		System.out.println("性别:女");
	}
}
/**
 * 具体访问者AgeVisitor
 */
public class AgeVisitor implements Visitor {
	@Override
	public void visit(ManElement manElement) {
		System.out.println("年龄:"+manElement.getAge());
	}
	@Override
	public void visit(WomanElement womanElement) {
		System.out.println("年龄:"+womanElement.getAge());
	}
}
  • 抽象元素
java 复制代码
/**
 * 抽象元素
 */
public interface Element {
	
	void accept(Visitor visitor);
	
}
  • 具体元素
java 复制代码
/**
 * 人
 */
public interface Person {
	String getName();
	Boolean isMan();
	Integer getAge();
}
/**
 * 具体元素ManElement 
 */
public class ManElement implements Person, Element{
	private String name;
	private Boolean isMan = true;
	private Integer age;
	public ManElement() {
	}
	public ManElement(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
	@Override
	public String getName() {
		return name;
	}
	@Override
	public Boolean isMan() {
		return isMan;
	}
	@Override
	public Integer getAge() {
		return age;
	}
	public Boolean getIsMan() {
		return isMan;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
}
/**
 * 具体元素WomanElement 
 */
public class WomanElement implements Person,Element{
	private String name;
	private Boolean isMan = false;
	private Integer age;
	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
	public WomanElement() {
	}
	public WomanElement(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String getName() {
		return name;
	}
	@Override
	public Boolean isMan() {
		return isMan;
	}
	@Override
	public Integer getAge() {
		return age;
	}
	public Boolean getIsMan() {
		return isMan;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
}
  • 客户端调用
java 复制代码
public static void main(String[] args) {
	ManElement manElement = new ManElement("张三", 30);
	WomanElement womanElement = new WomanElement("翠花", 18);
	List<Element> elements = new ArrayList<>();
	elements.add(manElement);
	elements.add(womanElement);
	NameVisitor nameVisitor = new NameVisitor();
	GenderVisitor genderVisitor = new GenderVisitor();
	AgeVisitor ageVisitor = new AgeVisitor();
	for (Element element : elements) {
		element.accept(nameVisitor);
		element.accept(genderVisitor);
		element.accept(ageVisitor);
	}
}

更多设计模式学习:

设计模式(1):介绍

设计模式(2):单例模式

设计模式(3):工厂模式

设计模式(4):建造者模式

设计模式(5):原型模式

设计模式(6):桥接模式

设计模式(7):装饰器模式

设计模式(8):组合模式

设计模式(9):外观模式

设计模式(10):享元模式

设计模式(11):适配器模式

设计模式(12):代理模式

设计模式(13):模板方法模式

设计模式(14):命令模式

设计模式(15):迭代器模式

设计模式(16):观察者模式

设计模式(17):中介者模式

设计模式(18):状态模式

设计模式(19):策略模式

设计模式(20):责任链模式

设计模式(21):备忘录模式

设计模式(22):解释器模式

设计模式(23):访问者模式

相关推荐
呼啦啦啦啦啦啦啦啦13 分钟前
【Redis】持久化机制
java·redis·mybatis
我想学LINUX1 小时前
【2024年华为OD机试】 (A卷,100分)- 微服务的集成测试(JavaScript&Java & Python&C/C++)
java·c语言·javascript·python·华为od·微服务·集成测试
空の鱼6 小时前
java开发,IDEA转战VSCODE配置(mac)
java·vscode
P7进阶路7 小时前
Tomcat异常日志中文乱码怎么解决
java·tomcat·firefox
小丁爱养花7 小时前
Spring MVC:HTTP 请求的参数传递2.0
java·后端·spring
CodeClimb7 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
等一场春雨7 小时前
Java设计模式 九 桥接模式 (Bridge Pattern)
java·设计模式·桥接模式
带刺的坐椅8 小时前
[Java] Solon 框架的三大核心组件之一插件扩展体系
java·ioc·solon·plugin·aop·handler
不惑_8 小时前
深度学习 · 手撕 DeepLearning4J ,用Java实现手写数字识别 (附UI效果展示)
java·深度学习·ui
费曼乐园9 小时前
Kafka中bin目录下面kafka-run-class.sh脚本中的JAVA_HOME
java·kafka