Java 编程之访问者模式详解

发布于:2025-07-06 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、前言

在日常开发中,我们经常需要对一组对象执行不同的操作,但又不希望在这些对象中添加太多的职责。这时候,访问者模式(Visitor Pattern)就像一位灵活的“快递员”,带着不同的“操作包裹”,穿梭在对象之间,完成任务。

本文将用快递员送货作为Java 实战示例,一步步带你搞懂这个访问者的设计模式。


二、访问者模式

访问者模式是一种行为型设计模式,它将要执行的操作封装到访问者对象中,使得你可以在不改变数据结构的前提下,定义作用于这些结构的新操作。

换句话说:访问者把操作从对象身上“移出去”,让对象接受访问者来“访问自己”,由访问者来做事。

类比快递员
想象你是一个快递员(访问者),你每天要送快递到不同的地方:

  • 公司,你送的是办公用品;
  • 学校,你送的是教科书;
  • 医院,你送的是药品。

每个地点(元素)都有不同的处理方式,但你不需要改变它们的结构,只需要实现“到访”这些地方时的具体逻辑即可。


三、结构类图表示

在这里插入图片描述

@startuml
interface Element {
  +accept(v: Visitor): void
}

interface Visitor {
  +visitCompany(c: Company): void
  +visitSchool(s: School): void
}

class Company implements Element {
  +accept(v: Visitor): void
}

class School implements Element {
  +accept(v: Visitor): void
}

class ConcreteVisitor implements Visitor {
  +visitCompany(c: Company): void
  +visitSchool(s: School): void
}
@enduml

四、代码用例说明

话不多说,让我们用java代码来对例子做实际的展示。

1. Element 接口

public interface Place {
    void accept(Visitor visitor);
}

2. 具体元素类:公司和学校

public class Company implements Place {
    public void accept(Visitor visitor) {
        visitor.visitCompany(this);
    }

    public String getOfficeSupplies() {
        return "办公用品";
    }
}

public class School implements Place {
    public void accept(Visitor visitor) {
        visitor.visitSchool(this);
    }

    public String getTextbooks() {
        return "教科书";
    }
}

3. Visitor 接口和实现类

public interface Visitor {
    void visitCompany(Company company);
    void visitSchool(School school);
}
public class DeliveryVisitor implements Visitor {
    @Override
    public void visitCompany(Company company) {
        System.out.println("送达:" + company.getOfficeSupplies());
    }

    @Override
    public void visitSchool(School school) {
        System.out.println("送达:" + school.getTextbooks());
    }
}

4. 客户端调用

import java.util.*;

public class Client {
    public static void main(String[] args) {
        List<Place> places = Arrays.asList(new Company(), new School());
        Visitor visitor = new DeliveryVisitor();

        for (Place place : places) {
            place.accept(visitor);
        }
    }
}

5. 输出结果:

送达:办公用品
送达:教科书

五、学习总结

访问者模式的本质,就是把“逻辑”从“元素”身上移出去,用一个“访问者”类专门来处理。

只要你记住这个例子:“快递员拜访各个地点,每个地点有自己的逻辑,但快递员说了算”,你就能在设计系统时恰如其分地使用它了。


六、适用场景

  • 数据结构稳定,但对其操作经常变动的系统。
  • 编译器中的语法树遍历。
  • 对象结构包含很多不同类,且你需要对它们执行各种无关操作时。

七、参考

《23种设计模式概览》

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到