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

🧩 使用建议

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

相关推荐
iCxhust5 分钟前
Deepseek给出的8255显示例程
c语言·开发语言·c++·单片机·嵌入式硬件
好奇的菜鸟10 分钟前
Java数据校验:确保数据完整性和正确性
java·开发语言
网安INF25 分钟前
深入理解汇编语言中的顺序与分支结构
开发语言·汇编·编程
m0_5261194029 分钟前
h5的aliplayer-min.js 加密视频会走到debugger
开发语言·javascript·音视频
端阳月七31 分钟前
C#面试问题61-80
开发语言·c#
网安INF1 小时前
密码学:解析Feistel网络结构及实现代码
java·网络安全·密码学·des·feistel
萝卜白菜。1 小时前
关于TongWeb数据源兼容mysql驱动的注意事项
java·mysql
失败才是人生常态1 小时前
Java实习面试题
java·开发语言
fanTuanye1 小时前
JavaWeb是什么?总结一下JavaWeb的体系
java·大数据·javaweb·基础·体系
庄小焱1 小时前
设计模式——中介者设计模式(行为型)
设计模式