访问者模式
定义
将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新操作;为数据结构中的每个元素提供多种访问方式,将对数据的操作与数据结构进行分离。
架构
抽象访问者:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作,该操作中的参数类型代表被访问的具体元素;
具体访问者:确定一个访问者访问元素的时候做些什么;
抽象元素:声明一个包含接收操作的接口,被接收的访问者对象作为接收方法的参数;
具体元素:实现被接收的访问者对象要做的操作;
对象结构:是一个包含元素角色的容器,提供让访问者对象遍历容器中所有元素的方法
应用场景
1、当对集合中的不同类型数据(类型数量稳定)进行多种操作的时候
2、对象结构稳定,但操作算法经常变化
3、对象结构中的对象需要提供多种不同且不相关的操作,而且要避让这些操作的变化影响对象的结构;
4、对象结构包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。
代码
Visitor(抽象访问者)
/**抽象访问者*/
public interface Visitor {
/**访问元素类入口*/
void visit(Element element);
}
VisitorA(具体访问者A)
public class VisitorA implements Visitor {
@Override
public void visit(Element element) {
System.out.println("访问者"+this.getClass().getSimpleName()+"----访问"+element.getClass().getSimpleName()+":"+element.opration());
}
}
VisitorB(具体访问者B)
public class VisitorB implements Visitor {
@Override
public void visit(Element element) {
System.out.println("访问者"+this.getClass().getSimpleName()+"----访问"+element.getClass().getSimpleName()+":"+element.opration());
}
}
Element(抽象元素)
/**抽象元素类*/
public interface Element {
/**和访问者绑定*/
void accept(Visitor visitor);
/**元素的具体行为*/
String opration();
}
ConcreteElementA(具体元素A)
/**
*
* Description:
* 具体元素类
* @author: mushi
* @Date: 2021/2/22 16:30
*/
public class ConcreteElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String opration(){
//元素的具体行为
return "我是元素A";
}
}
ConcreteElementB(具体元素B)
/**
*
* Description:
* 具体元素类
* @author: mushi
* @Date: 2021/2/22 16:32
*/
public class ConcreteElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String opration(){
//元素的具体行为
return "我是元素B";
}
}
ObjectStructure(对象结构)
/**
*
* Description:
* 对象结构
* @author: mushi
* @Date: 2021/2/22 16:34
*/
public class ObjectStructure {
//对象结构中包含的元素
private List<Element> list = new ArrayList<>();
/**通过访问者访问对象结构中的所有元素*/
public void accept(Visitor visitor){
Iterator<Element> iterator = list.iterator();
while (iterator.hasNext()){
iterator.next().accept(visitor);
}
}
/**管理对象结构中的元素*/
public void add(Element element){
list.add(element);
}
public void remove(Element element){
list.remove(element);
}
}
Test
public class Test {
public static void main(String[] args) {
//创建一个对象结构,并往对象结构中添加元素
ObjectStructure os = new ObjectStructure();
os.add(new ConcreteElementA());
os.add(new ConcreteElementB());
//创建一个访问者
Visitor visitor = new VisitorA();
//通过访问者访问对象结构中的所有元素
os.accept(visitor);
visitor = new VisitorB();
os.accept(visitor);
}
}
总结
先说一下以上代码的执行流程,方便通过代码执行流程来理解这个模式:
ObjectStructure.add(往对象结构中添加元素)=>
ObjectStructure.accept(添加访问者访问对象结构)=>
ConcreteElementA.accept(访问者到达元素类,访问具体元素)=>
VisitorA.visit(先前创建的具体访问者开始访问元素的具体行为)=>
ConcreteElementA.operation(元素的具体行为)
个人感觉有点责任链模式的味道,不过责任链是去匹配执行,这个是链式全部执行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南