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

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

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

请添加图片描述

简介

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

访问者模式解析

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

角色与职责

  • Visitor 访问者,为对象ConcreteElement类声明了visit方法。
  • ConcreteVisitor 具体访问者,实现Visitor的每一个方法。
  • ObjectStruture 能够枚举其他元素,用来允许访问者访问元素。
  • Element 接收访问者对象。
  • ConcreteElement 具体元素

访问者模式实例

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

①、定义访问者接口

定义元素各自所需的方法,这里定义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);
    }
}

运行结果
在这里插入图片描述
👍创作不易,可能有些语言不是很通畅,如有错误请指正,感谢观看!记得一键三连哦!👍

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

💓德德小建议:

理解设计模式不是一件简单的事情,需要不断的学习和动手去练习,才能理解。只有掌握好设计模式,才能够真正的理解SpringAOP和Mybatis的底层原理。各位读者可以和我一样,动手敲一敲代码,甚至用不同的例子来做,通过debug一步一步调试,还有就是多看看别人的例子。能够有助于理解!谢谢各位观看指点!❤️ ❤️ ❤️

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个有梦有戏的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值