美文网首页
访问者模式的使用

访问者模式的使用

作者: 文景大大 | 来源:发表于2022-07-01 14:36 被阅读0次

一、模式介绍

访问者模式通常包含如下几个角色:

  • 抽象元素,定义元素接受访问者访问的方法;
  • 具体元素,提供接受访问者访问的具体实现,以及自身的一些操作;
  • 抽象访问者,定义多个visit方法用来访问每一个具体元素,理论上visit方法个数等于具体元素个数;因此要求该模式使用场景是元素稳定不变的。
  • 具体访问者,实现对具体元素操作的访问;
  • 结构对象,维护具体元素的集合,提供方法接受具体访问者对集合中的所有元素进行访问;

通用的实现代码如下:

/**
 * 抽象元素
 * 定义接受访问者访问的方法
 * 所有具体元素都支持被访问者访问
 */
public interface IElement {
    void accept(IVisitor visitor);
}
/**
 * 具体元素A
 */
@Slf4j
public class ConcreteElementA implements IElement{
    @Override
    public void accept(IVisitor visitor) {
        // 访问者进行访问
        visitor.visit(this);
    }

    public void operation(){
        log.info("ConcreteElementA operation");
    }
}
/**
 * 具体元素B
 */
@Slf4j
public class ConcreteElementB implements IElement{
    @Override
    public void accept(IVisitor visitor) {
        // 访问者进行访问
        visitor.visit(this);
    }

    public void operation(){
        log.info("ConcreteElementB operation");
    }
}
/**
 * 抽象访问者
 */
public interface IVisitor {
    /**
     * 定义visit方法访问每一个具体的元素
     * 理论上visit方法个数和具体元素的个数是相等的
     * @param element
     */
    void visit(ConcreteElementA element);
    void visit(ConcreteElementB element);
}
/**
 * 具体访问者,实现对具体元素的访问操作
 */
public class ConcreteVisitor implements IVisitor{
    @Override
    public void visit(ConcreteElementA element) {
        element.operation();
    }

    @Override
    public void visit(ConcreteElementB element) {
        element.operation();
    }
}
public class ObjectStructure {
    private List<IElement> list = new ArrayList<>();

    /**
     * 需要被访问的具体元素初始化时都装入集合中
     */
    {
        this.list.add(new ConcreteElementA());
        this.list.add(new ConcreteElementB());
    }

    /**
     * 接待某个具体的访问者
     * @param visitor
     */
    public void accept(IVisitor visitor){
        // 带访问者依次参观具体元素
        for (IElement element : this.list) {
            element.accept(visitor);
        }
    }
}
@Slf4j
public class Main {
    public static void main(String[] args) {
        ObjectStructure collection = new ObjectStructure();
        IVisitor jack = new ConcreteVisitor();
        // 接待jack这个访问者
        collection.accept(jack);
    }
}

我们将如上的案例来做一个实际场景的类比:

  • ObjectStructure相当于一个家族的管家,具体元素类相当于每个房间里面的主人,家族里面主人的个数肯定是固定的,然后访问者来家族进行访问的时候,由管家进行接待accept(visitor)
  • 然后管家带领访问者依次去每个房间拜访主人element.accept(visitor)
  • 每个主人需要同意accept(visitor)访问者访问后,访问者才可以进行对当前主人的访问visitor.visit(this)
  • 然后这个主人才和访问者进行交流,展示自己operation

在这样的设计模式中,任何访问者想来拜访,只要让管家去接待一下即可,每个房间的主人们则完全不用操心,只需要固定地接受拜访并展示自己即可,对访问者的扩展十分方便。与此同时,倘若每个房间的主人有多项技能的话(唱歌、跳舞、吟诗、作画......),访问者可以自己定义想拜访主人都需要为自己展示什么才能,只要过了管家这一关即可,因为必须要管家给安排。

二、使用场景

  • JDK的NIO中的FileVisitor接口;
  • Spring中的BeanDefinitionVisitor类;

三、模式总结

3.1 优点

  • 解耦了数据结构和数据操作;
  • 可以很方便地扩展访问者角色,实现对不同数据集的不同操作,扩展性良好;
  • 元素具体类型可以是多样的,访问者均可操作;
  • 各个角色职责分离,符合单一职责原则;

3.2 缺点

  • 无法灵活增加元素类型,否则就得频繁改动访问者,违反了开闭原则;
  • 元素行为增删困难,需要改动访问者的调用行为,违反了开闭原则;
  • 访问者直接耦合了具体元素类,而没有以来抽象,违背了依赖倒置原则;

相关文章

  • 访问者模式,数据结构、操作的解耦?

    访问者模式,是谁来访问谁的,怎么访问的? 访问者模式,能使用在什么业务场景下呢? 访问者模式(Visitor Pa...

  • 访问者模式

    访问者模式属于行为型模式。访问者模式是一种将数据结构和数据操作分离的设计模式。访问者模式比较复杂,而且实际使用的地...

  • 访问者模式一篇就够了

    访问者模式介绍 最复杂的设计模式,并且使用频率不高,《设计模式》的作者评价为:大多情况下,你不需要使用访问者模式,...

  • 设计模式之访问者模式(23)

    访问者模式 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通...

  • c++访问者模式

    1.访问者模式简介    在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类...

  • Android 设计模式 - 访问者模式

    如何使用访问者模式 访问者模式将数据操作和数据结构分离,客户端使用用访问者对象去访问原有的数据结构,这样做的好处是...

  • 13.访问者模式 访问者模式也称为Visitor模式,使用这种模式后可以在不修改已有程序结构的前提下,通过额外添加...

  • 设计模式之访问者模式(visitor模式)

    引入访问者模式 访问者模式的实例 访问者模式分析 引入访问者模式 Visitor是访问者的意思。数据结构中保存着元...

  • 第5章 -行为型模式-访问者模式

    一、访问者模式的简介 二、访问者模式的优缺点 三、访问者模式的实例

  • 访问者模式

    一、访问者模式介绍 二、访问者模式代码实例

网友评论

      本文标题:访问者模式的使用

      本文链接:https://www.haomeiwen.com/subject/wjucbrtx.html