3.11设计模式——Visitor 访问者模式(行为型)

意图

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

结构

  • Visitor(访问者)为该对象结构中ConcreteElement(具体元素)的每一个类声明一个Visit操作,该操作的名字和特征标识了发送Visit请求给该访问者的那个类,这使得访问者可以确定正被访问元素的具体的类。这样访问者就可以通过该元素的特定接口直接访问它。
  • ConcreteVisitor(具体访问者)实现每个有Visitor声明的操作,每个操作实现本算法的一部分,而算法片段乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态。这一状态常常在遍历该结构的过程中累计结果。
  • Element(元素)定义以一个访问者为参数的Accept操作。
  • ConcreteElement(具体元素)实现以一个访问者为参数的Accept操作。
  • ObjectStructure(对象结构)能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个组合或者是一个集合,如一个列表或一个无序集合。

适用性

  • 一个对象结构包含很多类对象,它们有不同的接口,而用户想对这些对象实施一些依赖于具体类的操作。
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而又想要避免这些操作污染这些对象的类,Visitor使得用户可以将相关的操作集中起来定义再一个类中。当该对象结构被很多应用共享是,用Visitor模式让每个应用仅包含需要用到的操作。
  • 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对独有访问者的接口,这可能需要很大的代价。如果对象结构经常改变,那么可能还是在这些类中定义这些操作较好。

代码示例

java 复制代码
// Element接口
interface Element {
    void accept(Visitor visitor);
}

// ConcreteElement具体元素类
class ConcreteElementA implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visitConcreteElementA(this);
    }
}

class ConcreteElementB implements Element {
    @Override
    public void accept(Visitor visitor) {
        visitor.visitConcreteElementB(this);
    }
}

// Visitor访问者接口
interface Visitor {
    void visitConcreteElementA(ConcreteElementA element);
    void visitConcreteElementB(ConcreteElementB element);
}

// ConcreteVisitor具体访问者类
class ConcreteVisitor implements Visitor {
    @Override
    public void visitConcreteElementA(ConcreteElementA element) {
        System.out.println("访问者正在访问 ConcreteElementA");
    }

    @Override
    public void visitConcreteElementB(ConcreteElementB element) {
        System.out.println("访问者正在访问 ConcreteElementB");
    }
}

// ObjectStructure对象结构类
class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void addElement(Element element) {
        elements.add(element);
    }

    public void removeElement(Element element) {
        elements.remove(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}

// 示例用法
public class VisitorPatternExample {
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.addElement(new ConcreteElementA());
        objectStructure.addElement(new ConcreteElementB());

        Visitor visitor = new ConcreteVisitor();
        objectStructure.accept(visitor);
    }
}
  1. Element(元素)接口定义了一个接受访问者的方法 accept(Visitor visitor),该方法允许访问者访问元素。

  2. ConcreteElementA 和 ConcreteElementB 是具体元素类,它们实现了 Element 接口,并在 accept 方法中调用访问者的相应方法,将自身作为参数传递给访问者。

  3. Visitor(访问者)接口声明了访问具体元素的方法,例如 visitConcreteElementAvisitConcreteElementB

  4. ConcreteVisitor(具体访问者)类实现了 Visitor 接口,提供了对具体元素的访问方法的具体实现。

  5. ObjectStructure(对象结构)类维护了一个元素列表,并提供了一个接受访问者的方法 accept,在该方法中遍历元素列表,调用每个元素的 accept 方法,让访问者访问每个元素。

相关推荐
.格子衫.9 分钟前
Spring Boot 原理篇
java·spring boot·后端
多云几多33 分钟前
Yudao单体项目 springboot Admin安全验证开启
java·spring boot·spring·springbootadmin
Jabes.yang3 小时前
Java求职面试实战:从Spring Boot到微服务架构的技术探讨
java·数据库·spring boot·微服务·面试·消息队列·互联网大厂
聪明的笨猪猪3 小时前
Java Redis “高可用 — 主从复制”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
兮动人3 小时前
Spring Bean耗时分析工具
java·后端·spring·bean耗时分析工具
MESSIR223 小时前
Spring IOC(控制反转)中常用注解
java·spring
摇滚侠3 小时前
Spring Boot 3零基础教程,Demo小结,笔记04
java·spring boot·笔记
阿维的博客日记4 小时前
设计模式-代理模式
设计模式·代理模式
笨手笨脚の4 小时前
设计模式-迭代器模式
java·设计模式·迭代器模式·行为型设计模式
spencer_tseng5 小时前
Eclipse 4.7 ADT (Android Development Tools For Eclipse)
android·java·eclipse