23种设计模式-行为型模式之访问者模式(Java版本)

Java 访问者模式(Visitor Pattern)详解

🧠 什么是访问者模式?

访问者模式是一种行为型设计模式,它使得你可以在不修改对象结构的情况下,定义作用于该结构的操作。通过将操作从对象本身移到访问者类中,可以在不改变类的情况下,对其增加新的操作。

访问者模式的关键思想是将"数据"和"操作"分离,允许在对象结构不变的情况下添加新的操作。它通常用于对象结构是类群体的场景。


🎯 使用场景

  • 对象结构是一个包含很多类的集合,这些类的操作通常需要扩展。
  • 希望在不改变类的前提下,向类中添加新的操作。
  • 经常需要对同一对象结构执行不同的操作。

🏗️ 模式结构

  • Visitor(抽象访问者):声明对每一个具体元素的访问方法。
  • ConcreteVisitor(具体访问者):实现对每一个具体元素的访问操作。
  • Element(元素) :定义接受访问者的接口,通常包含一个 accept 方法。
  • ConcreteElement(具体元素) :实现 accept 方法,调用访问者的对应方法。
  • ObjectStructure(对象结构):管理所有元素对象的集合,提供一个可以迭代访问元素的机制。

✅ 示例:购物车的总价计算

抽象访问者类

java 复制代码
public interface Visitor {
    void visit(Book book);
    void visit(Fruit fruit);
}

具体访问者类

java 复制代码
public class ShoppingCartVisitor implements Visitor {

    @Override
    public void visit(Book book) {
        System.out.println("Book: " + book.getName() + ", Price: " + book.getPrice());
    }

    @Override
    public void visit(Fruit fruit) {
        System.out.println("Fruit: " + fruit.getName() + ", Price: " + fruit.getPrice());
    }
}

抽象元素类

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

具体元素类

java 复制代码
public class Book implements Item {
    private String name;
    private int price;

    public Book(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }

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

public class Fruit implements Item {
    private String name;
    private int price;

    public Fruit(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }

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

对象结构类(购物车)

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class ShoppingCart {
    private List<Item> items = new ArrayList<>();

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

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

客户端

java 复制代码
public class Client {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.addItem(new Book("Design Patterns", 50));
        cart.addItem(new Fruit("Apple", 2));

        ShoppingCartVisitor visitor = new ShoppingCartVisitor();
        cart.accept(visitor);  // 访问购物车中的每个项目
    }
}

✅ 优点

  • 可以在不修改类的前提下,为对象结构添加新的操作。
  • 避免了在每个元素类中添加"长长的if-else"语句。
  • 符合单一职责原则,每个访问者可以关注其对应的操作,避免了类中的方法变得过于庞大。

⚠️ 缺点

  • 访问者模式需要修改已有元素类以添加 accept 方法,可能会影响现有代码。
  • 如果对象结构变化频繁,扩展访问者的难度较大,因为访问者与对象结构密切耦合。
  • 需要创建多个访问者类,可能导致系统复杂度增加。

🧩 使用建议

访问者模式适合用于处理具有复杂对象结构的系统,并且这些对象结构的操作很容易在后期扩展。典型应用包括报表生成、文档结构遍历、数据模型操作等。

相关推荐
Sirens.5 分钟前
Java核心概念:抽象类、接口、Object类深度剖析
java·开发语言·github
Meteors.6 分钟前
23种设计模式——中介者模式 (Mediator Pattern)详解
java·设计模式·中介者模式
望获linux8 分钟前
【实时Linux实战系列】使用 u-trace 或 a-trace 进行用户态应用剖析
java·linux·前端·网络·数据库·elasticsearch·操作系统
焰火199915 分钟前
[Java]基于Spring的轻量级定时任务动态管理框架
java·后端
Seven9722 分钟前
Springboot 常见面试题汇总
java·spring boot
程序员阿鹏33 分钟前
49.字母异位词分组
java·开发语言·leetcode
云中隐龙42 分钟前
mac使用本地jdk启动elasticsearch解决elasticsearch启动时jdk损坏问题
java·elasticsearch·macos
CodeLongBear43 分钟前
苍穹外卖 Day12 实战总结:Apache POI 实现 Excel 报表导出全流程解析
java·excel
爱学习 爱分享1 小时前
mac idea 点击打开项目卡死
java·macos·intellij-idea
漠北七号1 小时前
有加密机,电脑贼卡顿怎么办
java