Java特性之设计模式【访问者模式】

一、访问者模式

概述

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作

主要解决

解决在稳定数据结构和易变操作之间的耦合问题,使得操作可以独立于数据结构变化

何时使用

  • 当需要对数据结构中的元素进行多种操作,并且这些操作之间存在一定的关联或依赖关系时,可以使用访问者模式。访问者模式可以通过在访问者中保存中间结果或状态,实现多个操作之间的数据共享和协作

优缺点

优点:

  • 单一职责原则:访问者模式符合单一职责原则,每个类只负责一项职责
  • 扩展性:容易为数据结构添加新的操作
  • 灵活性:访问者可以独立于数据结构变化

缺点:

  • 违反迪米特原则:元素需要向访问者公开其内部信息
  • 元素类难以变更:元素类需要维持与访问者的兼容
  • 依赖具体类:访问者模式依赖于具体类而不是接口,违反了依赖倒置原则

注意事项

  • 访问者模式可以用于功能统一,如报表生成、用户界面显示、拦截器和过滤器等

1. 各个角色介绍

1.1 访问者(Visitor)

  • 定义了访问元素的接口

1.2 具体访问者(Concrete Visitor)

  • 实现访问者接口,提供对每个具体元素类的访问和相应操作

1.3 元素(Element)

  • 定义了一个接受访问者的方法

1.4 具体元素(Concrete Element)

  • 实现元素接口,提供一个accept方法,允许访问者访问并操作

1.5 对象结构(Object Structure)(可选)

  • 定义了如何组装具体元素,如一个组合类

2. UML图

​ 我们将创建一个定义接受操作的 ComputerPart 接口。KeyboardMouseMonitorComputer 是实现了 ComputerPart 接口的实体类。我们将定义另一个接口 ComputerPartVisitor ,它定义了访问者类的操作。Computer 使用实体访问者来执行相应的动作

3. 具体例子和代码

角色分配

  • ComputerPart:电脑零件

    • Computer:电脑

    • Keyboard:键盘

    • Monitor:显示器

    • Mouse:鼠标

  • ComputerPartVisitor:电脑零件访问者

    • ComputerPartDisplayVisitor:电脑零件展示访问者

3.1 访问者接口及其实现类

  • ComputerPartVisitor
java 复制代码
package com.vinjcent.prototype.visitor;

/**
 * @author vinjcent
 * @description 电脑零件访问者(访问者角色)
 * @since 2024/6/5 19:43
 */
public interface ComputerPartVisitor {

    /**
     * 访问电脑
     *
     * @param computer 电脑
     */
    void visit(Computer computer);

    /**
     * 访问鼠标
     *
     * @param mouse 鼠标
     */
    void visit(Mouse mouse);

    /**
     * 访问键盘
     *
     * @param keyboard 键盘
     */
    void visit(Keyboard keyboard);

    /**
     * 访问显示器
     *
     * @param monitor 显示器
     */
    void visit(Monitor monitor);

}
  • ComputerPartDisplayVisitor
java 复制代码
package com.vinjcent.prototype.visitor;

/**
 * @author vinjcent
 * @description 电脑零件展示访问者
 * @since 2024/6/5 20:00
 */
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {

    @Override
    public void visit(Computer computer) {
        System.out.println("Displaying Computer.");
    }

    @Override
    public void visit(Mouse mouse) {
        System.out.println("Displaying Mouse.");
    }

    @Override
    public void visit(Keyboard keyboard) {
        System.out.println("Displaying Keyboard.");
    }

    @Override
    public void visit(Monitor monitor) {
        System.out.println("Displaying Monitor.");
    }

}

3.3 测试主函数

java 复制代码
package com.vinjcent.prototype.visitor;

/**
 * @author vinjcent
 * @description 访问者模式
 * @since 2024/6/5 20:07
 */
public class Main {

    public static void main(String[] args) {

        ComputerPart computer = new Computer();
        computer.accept(new ComputerPartDisplayVisitor());
        
    }

}
  • 测试结果

4. 使用场景

  • 当需要对一个对象结构中的对象执行多种不同的且不相关的操作时,尤其是这些操作需要避免"污染"对象类本身
相关推荐
qq_124987075319 分钟前
基于微信小程序的电子元器件商城(源码+论文+部署+安装)
java·spring boot·spring·微信小程序·小程序·毕业设计
吃喝不愁霸王餐APP开发者26 分钟前
基于Spring Cloud Gateway实现对外卖API请求的统一鉴权与流量染色
java·开发语言
a努力。28 分钟前
美团Java面试被问:Redis集群模式的工作原理
java·redis·后端·面试
一雨方知深秋38 分钟前
面向对象编程
java·封装·this·构造器·static关键字·成员变量·javabean实体类
资生算法程序员_畅想家_剑魔41 分钟前
Java常见技术分享-11-责任链模式
java·spring boot·责任链模式
计算机程序设计小李同学1 小时前
动漫之家系统设计与实现
java·spring boot·后端·web安全
程序员阿鹏2 小时前
责任链模式
java·spring·servlet·tomcat·maven·责任链模式
@淡 定2 小时前
Java内存模型(JMM)详解
java·开发语言
czhc11400756632 小时前
C# 1221
java·servlet·c#
黄俊懿2 小时前
【深入理解SpringCloud微服务】Seata(AT模式)源码解析——全局事务的回滚
java·后端·spring·spring cloud·微服务·架构·架构师