访问者模式(Visitor Pattern)

访问者模式(Visitor Pattern)

定义

访问者模式(Visitor Pattern)

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

该模式的主要思想是将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使得可以在不改变数据结构的前提下添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。

属于行为型模式。


适用场景

  1. 数据结构稳定,作用于数据结构的操作经常发生变化的场景;
  2. 需要数据结构与数据操作分离的场景;
  3. 需要对不同数据类型(元素)进行操作,而不使用分支判断具体类型的场景。

标准示例

  • Visitor(抽象访问者):定义一个访问具体元素的接口,该接口内部包含了对所有具体元素的访问方法。
  • ConcreteVisitor(具体访问者):实现Visitor接口,针对特定类型的元素执行具体访问操作。
  • Element(抽象元素):定义一个接受访问操作的接口,通常包含一个accept()方法,该方法接收一个访问者对象作为参数。
  • ConcreteElement(具体元素):实现了Element接口,存储了实际的数据,并提供接受访问者访问的方法实现。
  • ObjectStructure(对象结构):管理元素的集合,通常包含add、remove等方法以及一个遍历所有元素的accept()方法,该方法接收一个访问者对象作为参数,并遍历所有元素,让每个元素接受访问者的访问。

    代码:
java 复制代码
public interface IVisitor {
    void visit(ConcreteElementA element);
    void visit(ConcreteElementB element);
}
java 复制代码
public class ConcreteVisitorA implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.operationA();
        System.out.println( element.getClass().getSimpleName() + " : " + result);
    }

    public void visit(ConcreteElementB element) {
        int result = element.operationB();
        System.out.println( element.getClass().getSimpleName() + ": " + result);
    }
}
java 复制代码
public class ConcreteVisitorB implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.operationA();
        System.out.println(element.getClass().getSimpleName() + ": " + result);
    }
    public void visit(ConcreteElementB element) {
        int result = element.operationB();
        System.out.println( element.getClass().getSimpleName() + ": " + result);
    }
}
java 复制代码
public interface IElement {
    void accept(IVisitor visitor);
}
java 复制代码
public class ConcreteElementA implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public String operationA() {
        return this.getClass().getSimpleName();
    }

}
java 复制代码
public class ConcreteElementB implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public int operationB() {
        return new Random().nextInt(10);
    }
}
java 复制代码
public class ObjectStructure {
    private List<IElement> list = new ArrayList<IElement>();

    {
        this.list.add(new ConcreteElementA());
        this.list.add(new ConcreteElementB());
    }

    public void accept(IVisitor visitor) {
        for (IElement element : this.list) {
            element.accept(visitor);
        }
    }
}
java 复制代码
public class Test {

    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();	
        IVisitor visitorA = new ConcreteVisitorA();
        objectStructure.accept(visitorA);
        System.out.println("***************************************");
        IVisitor visitorB = new ConcreteVisitorB();
        objectStructure.accept(visitorB);
    }

}

输出结果:

shell 复制代码
ConcreteElementA: ConcreteElementA
ConcreteElementB: 5
***************************************
ConcreteElementA: ConcreteElementA
ConcreteElementB: 4

以上就是访问者模式全部内容,感谢阅读!

相关推荐
云烟成雨TD3 小时前
Spring AI Alibaba 1.x 系列【69】Token 用量统计
java·人工智能·spring
JAVA9653 小时前
JAVA面试-并发篇 03-使用synchronized doublecheck实现单例有什么坑
java·单例模式·面试
在繁华处3 小时前
Java从零到熟练(四):面向对象基础
java·开发语言
小江的记录本5 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
在繁华处5 小时前
Java从零到熟练(三):流程控制
java·开发语言·python
唐青枫5 小时前
Java Optional 实战指南:优雅处理空值与链式转换
java
一起学开源5 小时前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
逍遥德6 小时前
MQTT教程详解-04.SpringBoot集成MQTT(告别手动控制)
java·spring boot·物联网·中间件·iot·iotdb
语戚7 小时前
力扣 3161. 块放置查询:线段树解法(Java 实现)
java·算法·leetcode·面试·线段树·力扣·
我命由我123457 小时前
Android 开发问题:MlKitException: An internal error occurred during initialization.
android·java·java-ee·android jetpack·android-studio·androidx·android runtime