访问者模式 (Visitor Pattern) —— “万能导游“设计模式

🌟 核心思想

访问者模式允许你在不修改现有类结构的情况下,定义新的操作。就像旅行团参观城市,不同游客(访问者)对同一景点有不同的行为(拍照、写游记、购物等),而景点本身不需要改变。


🏛 现实世界类比:博物馆参观

  • 博物馆展品(元素):油画、雕塑、古董(固定不变)

  • 导游手册(访问者):普通游客、艺术家、历史学家(不同视角)

  • 导游(调度员):安排访问者参观各个展品


🏗 四大核心角色

角色作用类比
Visitor(访问者)定义对不同元素的访问逻辑不同类型的游客
ConcreteVisitor(具体访问者)实现具体的访问行为拍照游客/研究学者
Element(元素)定义accept()方法接收访问者博物馆展品
ObjectStructure(对象结构)维护元素集合,安排访问博物馆导览系统

📜 代码示例(Java实现)

1. 定义元素接口和具体元素

java

复制

// 展品接口(所有可被访问的元素必须实现)
interface Exhibit {
    void accept(Visitor visitor);
}

// 油画展品
class Painting implements Exhibit {
    public void accept(Visitor visitor) {
        visitor.visit(this); // 让访问者处理油画
    }
    
    public String getPaintingInfo() {
        return "《蒙娜丽莎》, 达芬奇, 1503年";
    }
}

// 雕塑展品
class Sculpture implements Exhibit {
    public void accept(Visitor visitor) {
        visitor.visit(this); // 让访问者处理雕塑
    }
    
    public String getSculptureMaterial() {
        return "大理石雕塑";
    }
}

2. 定义访问者接口和具体访问者

java

复制

// 访问者接口(定义所有可能的访问操作)
interface Visitor {
    void visit(Painting painting);
    void visit(Sculpture sculpture);
}

// 普通游客(具体访问者A)
class Tourist implements Visitor {
    public void visit(Painting painting) {
        System.out.println("游客拍照: " + painting.getPaintingInfo());
    }
    
    public void visit(Sculpture sculpture) {
        System.out.println("游客触摸: " + sculpture.getSculptureMaterial());
    }
}

// 艺术研究员(具体访问者B)
class ArtResearcher implements Visitor {
    public void visit(Painting painting) {
        System.out.println("研究员记录: " + painting.getPaintingInfo());
    }
    
    public void visit(Sculpture sculpture) {
        System.out.println("研究员测量: " + sculpture.getSculptureMaterial());
    }
}

3. 对象结构(博物馆)

java

复制

import java.util.ArrayList;
import java.util.List;

class Museum {
    private List<Exhibit> exhibits = new ArrayList<>();
    
    public void addExhibit(Exhibit exhibit) {
        exhibits.add(exhibit);
    }
    
    // 接待访问者参观所有展品
    public void accept(Visitor visitor) {
        for (Exhibit exhibit : exhibits) {
            exhibit.accept(visitor);
        }
    }
}

4. 客户端使用

java

复制

public class Client {
    public static void main(String[] args) {
        // 创建博物馆并添加展品
        Museum museum = new Museum();
        museum.addExhibit(new Painting());
        museum.addExhibit(new Sculpture());
        
        // 不同访问者参观
        Visitor tourist = new Tourist();
        museum.accept(tourist);
        /* 输出:
           游客拍照: 《蒙娜丽莎》, 达芬奇, 1503年
           游客触摸: 大理石雕塑
        */
        
        Visitor researcher = new ArtResearcher();
        museum.accept(researcher);
        /* 输出:
           研究员记录: 《蒙娜丽莎》, 达芬奇, 1503年
           研究员测量: 大理石雕塑
        */
    }
}

✅ 优点

✔ 开闭原则:新增访问者无需修改现有元素类
✔ 单一职责:将相关操作集中在一个访问者中
✔ 灵活性:可以在运行时选择不同访问者


❌ 缺点

✖ 元素接口变更困难:新增元素类型需要修改所有访问者
✖ 破坏封装:访问者可能需要访问元素的私有成员


🎯 适用场景

  • 对象结构稳定但需要频繁新增操作

  • 需要对同一组对象进行多种不相关的操作

  • 需要分离对象结构和操作逻辑

典型应用:

  • 编译器(AST遍历)

  • 文档处理(格式转换/统计)

  • UI事件处理


🔄 对比其他模式

模式目的关键区别
访问者模式解耦数据结构与操作双分派机制
策略模式封装算法单对象行为变化
迭代器模式遍历集合不修改元素行为

总结

访问者模式就像万能导游,让不同"游客"用各自的方式"参观"固定结构的对象集合。当你的系统需要在稳定结构上支持多变操作时,这个模式就是你的最佳选择!🚀

💡 设计箴言:访问者模式是"操作复杂,结构简单"场景的优雅解决方案,但过度使用可能导致系统过度复杂化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值