设计模式 - 访问者模式

目录

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

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

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


一. 前言

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

二. 实现

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

相关推荐
wyzqhhhh20 小时前
前端常见的设计模式
前端·设计模式
m0_7482336421 小时前
C++开发中的常用设计模式:深入解析与应用场景
javascript·c++·设计模式
Wind哥21 小时前
设计模式23种-C++实现
开发语言·c++·windows·设计模式
闲人编程1 天前
Python设计模式实战:用Pythonic的方式实现单例、工厂模式
开发语言·python·单例模式·设计模式·工厂模式·codecapsule·pythonic
御承扬1 天前
编程素养提升之EffectivePython(Builder篇)
python·设计模式·1024程序员节
杯莫停丶1 天前
设计模式之:享元模式
java·设计模式·享元模式
杯莫停丶1 天前
设计模式之:组合模式
设计模式·组合模式
Hero | 柒2 天前
设计模式之建造者模式
java·设计模式·1024程序员节
周杰伦_Jay2 天前
【常用设计模式全解析】创建型模式(聚焦对象创建机制)、结构型模式(优化类与对象的组合关系)、行为型模式(规范对象间的交互行为)
设计模式·架构·开源·交互·1024程序员节
杯莫停丶2 天前
设计模式之:外观模式
java·设计模式·外观模式