在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。
角色:
- Visitor:抽象的访问者
- ConcreteVistor:具体访问者
- ObjectStructure:提供一个高层接口,允许访问者访问元素
- Element:定义了accept方法,接收访问者对象
- ConcreteElement:具体元素,实现accept方法
package com.strife.pattern.visitor;
import java.time.Period;
import java.util.LinkedList;
import java.util.List;
/**
* 访问者模式
* 测评
* @author mengzhenghao
* @date 2022/6/2
*/
public class Visitor {
public static void main(String[] args) {
//成功测评
ObjectStructure successStructure = new ObjectStructure();
successStructure.attach(new Man());
successStructure.attach(new Man());
successStructure.attach(new Man());
successStructure.attach(new Woman());
AbstractAction success = new Success();
successStructure.display(success);
//失败测评
ObjectStructure failStructure = new ObjectStructure();
AbstractAction fail = new Fail();
failStructure.attach(new Man());
failStructure.attach(new Woman());
failStructure.display(fail);
}
}
/** 抽象访问者:Visitor */
abstract class AbstractAction {
/** 得到男性的测评结果 */
public abstract void getManResult(Man man);
/** 得到女性的测评结果 */
public abstract void getWomanResult(Woman woman);
}
/** 具体访问者:ConcreteVistor */
class Success extends AbstractAction {
@Override
public void getManResult(Man man) {
System.out.println("man success");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println("woman success");
}
}
/** 具体访问者:ConcreteVistor */
class Fail extends AbstractAction {
@Override
public void getManResult(Man man) {
System.out.println("man fail");
}
@Override
public void getWomanResult(Woman woman) {
System.out.println("woman fail");
}
}
/** 抽象元素:Element */
abstract class AbstractPerson {
/** 定义accept方法 */
public abstract void accept(AbstractAction visitor);
}
/**
* 具体元素:ConcreteElement
* 双分派
* 首先在客户端将具体状态作为参数传入Man(第一次分派)
* 然后Man类调用作为参数的 “具体方法” 中方法 getManResult ,同时将自己(this)作为参数传入(第二次分派)
*/
class Man extends AbstractPerson {
@Override
public void accept(AbstractAction visitor) {
visitor.getManResult(this);
}
}
/** 具体元素:ConcreteElement */
class Woman extends AbstractPerson {
@Override
public void accept(AbstractAction visitor) {
visitor.getWomanResult(this);
}
}
/** 数据结构(ObjectStructure):管理很多AbstractPerson */
class ObjectStructure {
private List<AbstractPerson> people = new LinkedList<>();
public void attach(AbstractPerson person) {
people.add(person);
}
public void detach(AbstractPerson person) {
people.remove(person);
}
/** 显示测评情况 */
public void display(AbstractAction action) {
for (AbstractPerson person : people) {
person.accept(action);
}
}
}