定义
- 表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变元素的类的前提下定义作用与这些元素的新操作。
模式动机
- 对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问者的对象来访问,不同的访问者其访问方式也有所不同。
访问者模式角色
- 抽象访问者: 一般通过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);
}
}
更多设计模式学习:
设计模式(23):访问者模式