• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

RomanLin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【设计模式与体系结构】行为型模式-访问者模式

简介

访问者模式(Visitor Pattern)是一种行为型设计模式,将数据结构与操作(算法)进行分离,使我们在不改变数据结构的前提下定义不同的操作于复杂数据结构的新操作(算法)。

访问者模式的优点

  1. 符合开闭原则:增加新的访问者类,不需要修改任何源代码,符合开闭原则
  2. 符合单一职责原则:相关操作都封装在一个访问者,便于维护和复用

访问者模式的缺点

  1. 若元素类需要发生变化,则不满足开闭原则,且变化成本巨大
  2. 违背依赖倒置原则:访问者依赖于具体元素,而非抽象
  3. 破坏封装性:由于访问者模式是双重委派机制,因此会破坏封装性,暴露出部分实现细节

访问者模式的使用场景

当数据结构较为复杂但稳定,且经常需要添加对这个数据结构的不同操作时,适合使用访问者模式。通过将数据结构与操作分离,可以确保对象结构的稳定性,同时允许灵活地添加新功能。

常用命令模板

角色 推荐命名模板 例子
访问者接口 Visitor Visitor
具体访问者 [动词]Visitor 或 [业务]Visitor SaveVisitor、ReportVisitor
元素接口 [名词]Element ShapeElement
具体元素 [具体类型]Element CircleElement、RectangleElement
对象结构 [名词]Structure ShapeStructure

正文

动物园中的动物种类一般是比较固定的,不常发生变化。而各种动物的行为等,明显是个性化的。那么就可以以动物园为例讲解访问者模式。

首先定义访问者模式通用的访问者接口 Visitor.java 和元素接口 Element.java:

// 通用访问者接口
public interface Visitor {
    void visit(Element element);
}

// 通用元素接口
public interface Element {
    void accept(Visitor visitor);
}

比方说某动物园的动物只有老虎和狮子,那么可以定义动物访问者接口 AnimalVisitor.java 和动物元素接口 AnimalElement.java,以及继承自动物元素接口 AnimalElement.java 的狮子类 Lion.java 与老虎类 Tiger.java:

// 动物访问者接口
public interface AnimalVisitor extends Visitor {
    void visitTiger(Tiger tiger);
    void visitLion(Lion lion);
}

// 动物元素接口
public interface AnimalElement extends Element {
    void accept(AnimalVisitor visitor);
}

// 狮子类
public class Lion implements AnimalElement {
    @Override
    public void accept(AnimalVisitor visitor) {
        visitor.visitLion(this);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 老虎类
public class Tiger implements AnimalElement {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    @Override
    public void accept(AnimalVisitor visitor) {
        visitor.visitTiger(this);
    }
}

各种动物的叫声都是不一致的,不妨定义一个叫声访问者类 Speak.java:

public class Speak implements AnimalVisitor {
    @Override
    public void visitTiger(Tiger tiger) {
        System.out.println(tiger + "虎啸");
    }

    @Override
    public void visitLion(Lion lion) {
        System.out.println(lion + "狮吼");
    }

    @Override
    public void visit(Element element) {
        System.out.println(element + "叫");
    }
}

对于客户端可以使用以下代码:

Speak speak = new Speak();
Lion lion = new Lion();
Tiger tiger = new Tiger();
lion.accept(speak);
tiger.accept(speak);

运行效果如下:
image

posted on 2026-07-07 23:04  RomanLin  阅读(3)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3