Java设计模式之访问者模式

一、是什么?

这是一个比较复杂且初理解比较困难的模式,先举个例子,帮助理解这个模式。

例子: 无人机群表演的例子,想让无人机群组合成不同的形状,不需要换一批无人机,我们只需要改变无人机群的代码就可以了,不用改变无人机的硬件(高度器和方向器),输入不同的代码,无人机就可以做不同的动作。

定义: 封装一些作用于某种数据结构(无人机硬件)的各元素(高度器)的操作(高低),它可以在不改变数据结构的前提下定义作用于这些元素的新的操作(代码)。

这个例子中,【数据结构】:无人机或无人机硬件;【各元素】:高度器和方向器;【操作】:飞多高或者往哪飞;【代码】:访问者。

二、类图

  • Code:是抽象访问者
  • ConcreteCode:是一个具体的访问者 实现每个由Code声明的操作,是每个操作实现的部分
  • UAVGroup:无人机群,能枚举他的元素,可以提供一个高层的接口,用来允许访问者访问元素
  • UAV:无人机抽象,声明了公共方法,接收一个访问者对象
  • LeaderUAV:为具体的元素,实现了light方法

转换成我们的例子

在这里插入图片描述

三、例子实现

UAV:抽象无人机,定义了无人机的公共属性和公共行为。其中executeCode用于执行代码,让代码访问控制无人机。

public abstract class UAV {

    // 无人机编号
    public int id;

    /**
     * 灯光
     */
    public abstract void light();
  
    /**
     * 上升高度
     *
     * @param height
     */
    public void riseHeight(int height) {

        System.out.println("【"+ this.id +"】 号上升" + height + "米");
    }


    /**
     * 下降高度
     *
     * @param height
     */
    public void downHeight(int height) {

        System.out.println("【"+ this.id +"】 号下降" + height + "米");
    };


    /**
     * 改变方向距离
     *
     * @param direction  方向
     * @param distance 距离
     */
    public void changeDirection(String direction, int distance) {

        // 打印往哪个方向飞多少米
        System.out.println("【"+ this.id +"】 号往" + direction + "方向飞" + direction + "米");
    }


    /**
     * 让代码控制自己
     *
     * @param code
     */
    public void executeCode(Code code) {

        code.controlUAV(this);
    }
}

LeaderUAV :具体的无人机,领头无人机。

public class LeaderUAV extends UAV{

    public LeaderUAV(int id) {

        this.id = id;
        light();
    }

    @Override
    public void light() {

        System.out.println("【"+ this.id +"】 号开启迪斯科灯");

    }
}

GeneralUAV :具体的无人机,普通无人机。

public class GeneralUAV extends UAV{

    public GeneralUAV(int id) {

        this.id = id;
        light();
    }


    @Override
    public void light() {

        System.out.println("【"+ this.id +"】 号开启绿光");
    }
}

UAVGroup :无人机群,提供访问者访问的方法。

public class UAVGroup extends ArrayList<UAV> {


    /**
     * 无人机群执行代码
     *
     * @param code
     */
    public void executeCode(Code code) {

        this.forEach(uav -> uav.executeCode(code));
    }
}

Code:代码抽象。

public abstract class Code {

    // 控制无人机
    public abstract void controlUAV(UAV uav);

}

ConcreteCode$1:具体的代码

public class ConcreteCode$1 extends Code{

    @Override
    public void controlUAV(UAV uav) {

        if (uav instanceof LeaderUAV) {
            // 上升20米
            uav.riseHeight(20);
        } else {

            // 往北飞五米
            uav.changeDirection("北", new Random().nextInt(50));
            // 上升五米
            uav.riseHeight(10);
            // 再下降五米
            uav.d	ownHeight(5);

        }

    }

}

Client:环境类,使用模式的地方。

public class Client {


    public static void main(String[] args) {

        UAVGroup uavs = new UAVGroup();
        uavs.add(new LeaderUAV(1));
        uavs.add(new GeneralUAV(2));
        uavs.add(new GeneralUAV(3));
        uavs.add(new GeneralUAV(4));

        Code code = new ConcreteCode$1();
        uavs.executeCode(code);
    }
}

执行结果:

无人机集群想展示不同的表演,只需要将new ConcreteCode$1() 改成其他的代码即可。

在这里插入图片描述

四、优缺点

优点:

  • 符合单一职责原则
  • 扩展性好
  • 灵活性好

缺点:

因为本文中访问者依赖的是抽象,所以不存在被访者种类扩展难和违背依赖倒置原则的问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

吖土豆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值