【设计模式】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一步一步调试,还有就是多看看别人的例子。能够有助于理解!谢谢各位观看指点!❤️ ❤️ ❤️
相关文章
|
2天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
2天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
2天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
2天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
|
2天前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
|
8天前
|
设计模式 算法 Java
Java中的设计模式及其应用
【4月更文挑战第18天】本文介绍了Java设计模式的重要性及分类,包括创建型、结构型和行为型模式。创建型模式如单例、工厂方法用于对象创建;结构型模式如适配器、组合关注对象组合;行为型模式如策略、观察者关注对象交互。文中还举例说明了单例模式在配置管理器中的应用,工厂方法在图形编辑器中的使用,以及策略模式在电商折扣计算中的实践。设计模式能提升代码可读性、可维护性和可扩展性,是Java开发者的必备知识。
|
11天前
|
设计模式 算法 Java
小谈设计模式(30)—Java设计模式总结
小谈设计模式(30)—Java设计模式总结
|
12天前
|
设计模式 存储 Java
Java设计模式:解释一下单例模式(Singleton Pattern)。
`Singleton Pattern`是Java中的创建型设计模式,确保类只有一个实例并提供全局访问点。它通过私有化构造函数,用静态方法返回唯一的实例。类内静态变量存储此实例,对外仅通过静态方法访问。
16 1
|
16天前
|
设计模式 算法 Java
23种设计模式,模板方法模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】模板方法模式是一种行为设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些特定步骤。
15 0
|
17天前
|
设计模式 Java
23种设计模式,状态模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】状态模式是一种行为设计模式,允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
29 4