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

🧩 使用建议

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

相关推荐
weixin_445402307 小时前
Python游戏中的碰撞检测实现
jvm·数据库·python
夕除7 小时前
js--6
java·开发语言
ytttr8737 小时前
C#实现海康威视智能车牌识别
开发语言·c#
梵刹古音7 小时前
【C语言】 关键字与用户标识符
c语言·开发语言
悟能不能悟7 小时前
grpc协议
开发语言
四维碎片7 小时前
【Qt】代理(Delegate)的使用
开发语言·qt
手握风云-7 小时前
JavaEE 进阶第十三期:Spring Ioc & DI,从会用容器到成为容器(下)
java·spring·java-ee
Andy&lin7 小时前
【医疗】智慧病房APP原型模板
设计模式·产品运营·人机交互·交互·健康医疗
组合缺一7 小时前
论 AI Skills 分布式发展的必然性:从单体智能到“云端大脑”的跃迁
java·人工智能·分布式·llm·mcp·skills
砚边数影7 小时前
决策树原理(一):信息增益与特征选择 —— Java 实现 ID3 算法
java·数据库·决策树·机器学习·kingbase·数据库平替用金仓·金仓数据库