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

🧩 使用建议

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

相关推荐
wei_shuo22 分钟前
飞算 JavaAI 开发助手:深度学习驱动下的 Java 全链路智能开发新范式
java·开发语言·飞算javaai
熊猫钓鱼>_>22 分钟前
用Python解锁图像处理之力:从基础到智能应用的深度探索
开发语言·图像处理·python
GO兔33 分钟前
开篇:GORM入门——Go语言的ORM王者
开发语言·后端·golang·go
欧阳秦穆44 分钟前
apoc-5.24.0-extended.jar 和 apoc-4.4.0.36-all.jar 啥区别
java·jar
好开心啊没烦恼1 小时前
Python 数据分析:numpy,抽提,整数数组索引与基本索引扩展(元组传参)。听故事学知识点怎么这么容易?
开发语言·人工智能·python·数据挖掘·数据分析·numpy·pandas
岁忧1 小时前
(LeetCode 面试经典 150 题 ) 58. 最后一个单词的长度 (字符串)
java·c++·算法·leetcode·面试·go
Java初学者小白1 小时前
秋招Day14 - Redis - 应用
java·数据库·redis·缓存
代码老y1 小时前
Spring Boot + 本地部署大模型实现:优化与性能提升
java·spring boot·后端
码农秋1 小时前
设计模式系列(10):结构型模式 - 桥接模式(Bridge)
设计模式·桥接模式
GodKeyNet1 小时前
设计模式-桥接模式
java·设计模式·桥接模式