访问者模式

定义

将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新操作;为数据结构中的每个元素提供多种访问方式,将对数据的操作与数据结构进行分离。

架构

抽象访问者:定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作,该操作中的参数类型代表被访问的具体元素;
具体访问者:确定一个访问者访问元素的时候做些什么;
抽象元素:声明一个包含接收操作的接口,被接收的访问者对象作为接收方法的参数;
具体元素:实现被接收的访问者对象要做的操作;
对象结构:是一个包含元素角色的容器,提供让访问者对象遍历容器中所有元素的方法

应用场景

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(元素的具体行为)

个人感觉有点责任链模式的味道,不过责任链是去匹配执行,这个是链式全部执行。

posted @   有锦  阅读(3)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示