设计模式 - 访问者模式

目录

[一. 前言](#一. 前言)

[二. 实现](#二. 实现)

[三. 优缺点](#三. 优缺点)


一. 前言

访问者模式,即在不改变聚合对象内元素的前提下,为聚合对象内每个元素提供多种访问方式,即聚合对象内的每个元素都有多个访问者对象。访问者模式主要解决稳定的数据结构和易变元素的操作之间的耦合问题。

二. 实现

Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作。

ConcreteVisitor:具体访问者,存储遍历过程中的累计结果。

ObjectStructure:对象结构,可以是组合结构,或者是一个集合。

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

public class Customer implements Element {
    private String name;
    private List<Order> orders = new ArrayList<>();

    Customer(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    void addOrder(Order order) {
        orders.add(order);
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
        for (Order order : orders) {
            order.accept(visitor);
        }
    }
}

public class Order implements Element {
    private String name;
    private List<Item> items = new ArrayList();

    Order(String name) {
        this.name = name;
    }

    Order(String name, String itemName) {
        this.name = name;
        this.addItem(new Item(itemName));
    }

    String getName() {
        return name;
    }

    void addItem(Item item) {
        items.add(item);
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);

        for (Item item : items) {
            item.accept(visitor);
        }
    }
}

public class Item implements Element {
    private String name;

    Item(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
java 复制代码
class CustomerGroup {
    private List<Customer> customers = new ArrayList<>();

    void accept(Visitor visitor) {
        for (Customer customer : customers) {
            customer.accept(visitor);
        }
    }

    void addCustomer(Customer customer) {
        customers.add(customer);
    }
}
java 复制代码
public interface Visitor {
    void visit(Customer customer);

    void visit(Order order);

    void visit(Item item);
}
java 复制代码
public class GeneralReport implements Visitor {
    private int customersNo;
    private int ordersNo;
    private int itemsNo;

    public void visit(Customer customer) {
        System.out.println(customer.getName());
        customersNo++;
    }

    public void visit(Order order) {
        System.out.println(order.getName());
        ordersNo++;
    }

    public void visit(Item item) {
        System.out.println(item.getName());
        itemsNo++;
    }

    public void displayResults() {
        System.out.println("Number of customers: " + customersNo);
        System.out.println("Number of orders:    " + ordersNo);
        System.out.println("Number of items:     " + itemsNo);
    }
}
java 复制代码
public class Client {
    public static void main(String[] args) {
        Customer customer1 = new Customer("customer1");
        customer1.addOrder(new Order("order1", "item1"));
        customer1.addOrder(new Order("order2", "item1"));
        customer1.addOrder(new Order("order3", "item1"));

        Order order = new Order("order_a");
        order.addItem(new Item("item_a1"));
        order.addItem(new Item("item_a2"));
        order.addItem(new Item("item_a3"));
        Customer customer2 = new Customer("customer2");
        customer2.addOrder(order);

        CustomerGroup customers = new CustomerGroup();
        customers.addCustomer(customer1);
        customers.addCustomer(customer2);

        GeneralReport visitor = new GeneralReport();
        customers.accept(visitor);
        visitor.displayResults();
    }
}
java 复制代码
customer1
order1
item1
order2
item1
order3
item1
customer2
order_a
item_a1
item_a2
item_a3
Number of customers: 2
Number of orders:    4
Number of items:     6

三. 优缺点

优点

  1. 符合单一职责原则,即数据的存储和操作分别由对象结构类和访问者类实现。

  2. 优秀的扩展性和灵活性。

缺点

  1. 具体元素对访问者公布了其细节,违反了迪米特法则。

  2. 具体元素的增加将导致访问者类的修改,违反了开闭原则。

  3. 访问者类依赖了具体类而不是抽象,违反了依赖倒置原则。

JDK中的访问者模式

javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor

javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor

相关推荐
深海鱼在掘金5 小时前
从 Claude Code 泄露源码看工程架构:第五章 —— 工具框架的三层装配线
人工智能·设计模式·架构
深海鱼在掘金5 小时前
从Claude Code泄露源码看工程架构:第四章—— 一次请求的完整生命周期与流式执行引擎设计
人工智能·设计模式·命令行
geovindu7 小时前
go: Bridge Pattern
开发语言·设计模式·golang·软件构建·桥接模式
钝挫力PROGRAMER8 小时前
Java中如何优雅管理接口的多个实现
java·设计模式
CPUOS201016 小时前
嵌入式C语言高级编程之MVC设计模式
c语言·设计模式·mvc
张涛酱1074561 天前
Subagent Orchestration 深入解析:多Agent协作的层级架构
spring·设计模式·ai编程
小江的记录本1 天前
【系统设计】《2026高频经典系统设计题》(秒杀系统、短链接系统、订单系统、支付系统、IM系统、RAG系统设计)(完整版)
java·后端·python·安全·设计模式·架构·系统架构
楼田莉子1 天前
同步/异步日志系统:日志器管理器模块\全局接口\性能测试
linux·服务器·开发语言·c++·后端·设计模式
Meya11271 天前
U位资产管理系统:数据中心“最后一公里“的精细化治理
设计模式·开源·交互
回忆2012初秋2 天前
工厂方法模式完整实现:GPS转换
设计模式·工厂方法模式