设计模式 - 访问者模式

目录

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

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

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


一. 前言

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

二. 实现

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

相关推荐
c++之路2 小时前
C++ 设计模式全总结
java·c++·设计模式
爱吃牛肉的大老虎4 小时前
Spring中用到的设计模式
java·spring·设计模式
代码中介商4 小时前
C++四大设计模式:单例、工厂、观察者、策略
java·c++·设计模式
basketball6165 小时前
设计模式入门:3. 适配器模式详解 C++实现
c++·设计模式·适配器模式
AI大法师6 小时前
最小视觉系统怎么搭:Logo、颜色、字体、模板和品牌介绍先做什么
人工智能·设计模式·新媒体运营
geovindu8 小时前
python: N-Barrier Pattern
开发语言·python·设计模式·屏障模式
basketball61611 小时前
设计模式入门:2. 工厂模式详解 C++实现
开发语言·c++·设计模式
basketball61611 小时前
设计模式入门:1. 单例模式详解 C++实现
c++·单例模式·设计模式
小马爱打代码11 小时前
Spring源码中的设计模式实战:从理论到源码的深度解析
java·spring·设计模式
WiLL12 小时前
AI 时代下的 SaaS: Skill As A Service (一)
设计模式·架构