【设计模式】Java设计模式 - 访问者模式

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

Java设计模式 - 访问者模式

😄 不断学习才是王道
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆 一个有梦有戏的人 @怒放吧德德
🌝分享学习心得,欢迎指正,大家一起学习成长!

java设计模式2.jpg

简介

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

访问者模式解析

访问者模式主要是将数据操作和数据结构分离开来,解决他们的耦合性问题。就是在访问类里面添加对外提供接待访问者的接口。
浅浅的理解,实际上就是有个元素接口类,里面包含未实现的方法,并且需要将访问者接口类对象带进去;在具体扩展的实体类中实现了元素接口类的方法,也就是调用了访问者对象的方法,这就相当于真正实现的方法都是由访问者接口类的子类去实现,这就形成了元素实体的可扩展,访问者的可扩展,并且他们都互不影响。
原理UML如图:
访问者模式.jpg

角色与职责

  • Visitor 访问者,为对象ConcreteElement类声明了visit方法。
  • ConcreteVisitor 具体访问者,实现Visitor的每一个方法。

    • ObjectStruture 能够枚举其他元素,用来允许访问者访问元素。
    • Element 接收访问者对象。
    • ConcreteElement 具体元素

访问者模式实例

采用汽车的例子来理解访问者模式,定义元素接口,将访问者接口对象带入,在具体的元素类中,通过访问者去调用相应方法。则访问者接口定义了元素所需的方法,由具体的访问者类去实现,数据结构是用来对元素进行管理,管理访问者能否访问元素。
类图:
image.png

代码如下:

①、定义访问者接口

定义元素各自所需的方法,这里定义vidit方法,通过参数来区分。

package com.lyd.demo.visitor;

import com.lyd.demo.element.car.Benz;
import com.lyd.demo.element.car.HongQi;

/**
 * @Author: lyd
 * @Description: 访问者接口
 * @Date: 2022-09-04
 */
public interface ICarPartVisitor {
    public void visit(Benz benz);
    public void visit(HongQi hongQi);
}

②、定义具体访问者

编写所有具体元素的业务

package com.lyd.demo.visitor;
import com.lyd.demo.element.car.Benz;
import com.lyd.demo.element.car.HongQi;
/**
 * @Author: lyd
 * @Description: 具体访问者方法
 * @Date: 2022-09-04
 */
public class CarDisplayVisitor implements ICarPartVisitor {
    @Override
    public void visit(Benz benz) {
        System.out.println(" 奔驰旗舰店汽车 ");
    }
    @Override
    public void visit(HongQi hongQi) {
        System.out.println(" 红旗旗舰店汽车 ");
    }
}

③、定义元素实体接口

带入访问者接口类对象,由具体的元素去实现,通过访问者调用方法。

package com.lyd.demo.element;
import com.lyd.demo.visitor.ICarPartVisitor;
/**
 * @Author: lyd
 * @Description: 元素实体接口类
 * @Date: 2022-09-04
 */
public interface ICar {
    public void accept(ICarPartVisitor carPartVisitor);
}

④、定义具体元素类

这里使用了双分派,将具体状态传递到Benz中,完成第一次分派。
通过访问者调用具体的方法,并且将自身对象作为参数,完成第二次分派。
(红旗类也是如此)

package com.lyd.demo.element.car;
import com.lyd.demo.element.ICar;
import com.lyd.demo.visitor.ICarPartVisitor;
/**
 * @Author: lyd
 * @Description: 扩展的实体类 - 奔驰
 * @Date: 2022-09-04
 */
public class Benz implements ICar {
    @Override
    public void accept(ICarPartVisitor carPartVisitor) {
        carPartVisitor.visit(this); // 将本身带过去
    }
}

⑤、定义数据结构

添加具体元素进来,通过循环遍历去调用各自的方法。

package com.lyd.demo.structure;
import com.lyd.demo.element.ICar;
import com.lyd.demo.visitor.ICarPartVisitor;
import java.util.LinkedList;
import java.util.List;
/**
 * @Author: lyd
 * @Description: 数据结构
 * @Date: 2022-09-04
 */
public class ObjectStructure {
    // 聚合
    private List<ICar> cars = new LinkedList<ICar>();
    // 添加到链表
    public void attach(ICar car) {
        this.cars.add(car);
    }
    // 缩减链表
    public void remove(ICar car) {
        this.cars.remove(car);
    }
    // 显示
    public void display(ICarPartVisitor carPartVisitor) {
        for (ICar car : cars) {
            car.accept(carPartVisitor);
        }
    }
}

⑥、测试

通过数据结构将对象添加进去,在通过具体的访问者去统一调用方法

package com.lyd.demo.test;
import com.lyd.demo.element.car.Benz;
import com.lyd.demo.element.car.HongQi;
import com.lyd.demo.structure.ObjectStructure;
import com.lyd.demo.visitor.CarDisplayVisitor;
/**
 * @Author: lyd
 * @Description: 测试
 * @Date: 2022-09-04
 */
public class VisitorTest {
    public static void main(String[] args) {
        // 创建对象
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.attach(new Benz());
        objectStructure.attach(new HongQi());
        CarDisplayVisitor carDisplayVisitor = new CarDisplayVisitor();
        objectStructure.display(carDisplayVisitor);
    }
}

运行结果
image.png

👍创作不易,可能有些语言不是很通畅,如有错误请指正,感谢观看!记得一键三连哦!👍

今天的内容理解不是那么简单,但实质上除了设计模式的思路,其实就是Java的面向对象知识,只要肯动手多敲,就容易理解。

💓德德小建议:

理解设计模式不是一件简单的事情,需要不断的学习和动手去练习,才能理解。只有掌握好设计模式,才能够真正的理解SpringAOP和Mybatis的底层原理。各位读者可以和我一样,动手敲一敲代码,甚至用不同的例子来做,通过debug一步一步调试,还有就是多看看别人的例子。能够有助于理解!谢谢各位观看指点!❤️ ❤️ ❤️
相关文章
|
25天前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
38 0
[Java]23种设计模式
|
9天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
1月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
1月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
31 3
|
2月前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
|
2月前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
1月前
|
设计模式 Java
Java设计模式
Java设计模式
28 0
|
1月前
|
设计模式 Java
Java设计模式之外观模式
这篇文章详细解释了Java设计模式之外观模式的原理及其应用场景,并通过具体代码示例展示了如何通过外观模式简化子系统的使用。
29 0
|
1月前
|
设计模式 Java
Java设计模式之桥接模式
这篇文章介绍了Java设计模式中的桥接模式,包括桥接模式的目的、实现方式,并通过具体代码示例展示了如何分离抽象与实现,使得两者可以独立变化。
43 0
|
1月前
|
设计模式 Java
Java设计模式之适配器模式
这篇文章详细讲解了Java设计模式中的适配器模式,包括其应用场景、实现方式及代码示例。
42 0