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 方法,可能会影响现有代码。
  • 如果对象结构变化频繁,扩展访问者的难度较大,因为访问者与对象结构密切耦合。
  • 需要创建多个访问者类,可能导致系统复杂度增加。

🧩 使用建议

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

相关推荐
步行cgn22 分钟前
Spring c 命名空间注入详解
java·后端·spring
明月_清风40 分钟前
Maven 到底是什么?一篇文章搞懂 Java 项目构建与依赖管理
java·后端·maven
aramae1 小时前
MySQL复合查询(8)
java·c语言·开发语言·后端·算法
Rain的Java大神之路2 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog2 小时前
Java 接入Redis: 通用命令与键管理
java·服务器·redis
Wang's Blog2 小时前
Java 接入Redis: 列表集合与有序集合操作命令
java·服务器·redis
Ivanqhz3 小时前
SVD++算法
java·服务器·网络·深度学习·神经网络
qq_2518364573 小时前
springboot vue3 开发实现 拼豆管理系统
java·开发语言·ai编程
caoerzhong4 小时前
JeeWMS 开源仓库管理系统全景解读:一套 Java WMS 如何把 WMS/OMS/BMS/TMS 装进同一个系统
java·开源
曹牧4 小时前
Java集合框架:List、ArrayList、Map 和 HashMap
java