命令模式(Command Pattern) 实例

命令模式(Command Pattern) 实例

目录

例子-遥控器:

类图:

代码:

接口 Command

开关 OpenClose

频道切换 ChannelSwitch

音量 Device 加其他的接口

开关命令 SwitchInvoke

频道命令 SwitchInvoke

音量命令 SwitchInvoke

灯泡 SwitchInvoke

电风扇 SwitchInvoke

电视 SwitchInvoke

命令调用 SwitchInvoke

测试:

结果:

分析

总结:


  在上一个例子命令模式中,并没有出现类图中Receiver的角色,现在风扇要换挡,电视要换台,加减音量。这时候该怎么做?

思考

    电灯只有两个动作: 开和关

    风扇有四个动作: 开、关、加挡和减挡

    电视有六个动作: 开、关、加台、减台、加音量和减音量

    把命令分成三种,然后加入一个Receiver 去接三种的命令

 

例子-遥控器:

类图:

 

 

代码:

接口 Command

public interface Command {
    void exe(); // 执行命令操作
    void unexe(); // 反执行命令操作
}

 

开关 OpenClose

public interface OpenClose {
    void on(); // 打开
    void off();// 关闭
}

 

频道切换 ChannelSwitch

public interface ChannelSwitch extends OpenClose {
    void channelUp(); // 频道+或是换挡或是切换模式
    void channelDown(); // 频道-或是减挡或是切换模式
}

 

音量 Device 加其他的接口

public interface Device extends OpenClose, ChannelSwitch {
    void volumeUp(); // 音量+
    void volumeDown(); // 音量-
}

 

开关命令 SwitchInvoke

public class OpenCloseCommand implements Command {
    private Device device;// 此处持有高级设备接口。
    public OpenCloseCommand(Device device) {
        this.device = device;
    }
    @Override
    public void exe() {
        device.on();// 开机
    }
    @Override
    public void unexe() {
        device.off();// 关机
    }
}

 

频道命令 SwitchInvoke

public class ChannelCommand implements Command {
    private Device device;
    public ChannelCommand(Device device) {
        this.device = device;
    }
    @Override
    public void exe() {
        device.channelUp();
    }
    @Override
    public void unexe() {
        device.channelDown();
    }
}

 

音量命令 SwitchInvoke

public class VolumeCommand implements Command {
    private Device device;
    public VolumeCommand(Device device) {
        this.device = device;
    }
    @Override
    public void exe() {
        device.volumeUp(); // 调高音量或是温度
    }
    @Override
    public void unexe() {
        device.volumeDown(); // 降低音量或是温度
    }
}

 

灯泡 SwitchInvoke

public class Bulb implements Device {
    @Override
    public void on() {
        System.out.println("打开电灯");
    }
    @Override
    public void off() {
        System.out.println("关闭电灯");
    }
    @Override
    public void channelUp() {
        // 没有这个内容,啥都不做
    }
    @Override
    public void channelDown() {
        // 没有这个内容,啥都不做
    }
    @Override
    public void volumeUp() {
        // 没有这个内容,啥都不做
    }
    @Override
    public void volumeDown() {
        // 没有这个内容,啥都不做
    }
}

 

电风扇 SwitchInvoke

public class ElectricFan implements Device {
    @Override
    public void on() {
        System.out.println("打开电风扇,风扇转动。");
    }
    @Override
    public void off() {
        System.out.println("关闭电风扇,风扇慢慢停止。");
    }
    @Override
    public void channelUp() {
        System.out.println("加档,风扇加速转动。");
    }
    @Override
    public void channelDown() {
        System.out.println("减档,风扇减速转动。");
    }
    @Override
    public void volumeUp() {
        // 没有这个内容,啥都不做
    }
    @Override
    public void volumeDown() {
        // 没有这个内容,啥都不做
    }
}

 

电视 SwitchInvoke

public class Television implements Device {
    @Override
    public void on() {
        System.out.println("打开电视,屏幕亮起。");
    }
    @Override
    public void off() {
        System.out.println("关闭电视。");
    }
    @Override
    public void channelUp() {
        System.out.println("电视往上换频道+");
    }
    @Override
    public void channelDown() {
        System.out.println("电视往下换频道-");
    }
    @Override
    public void volumeUp() {
        System.out.println("电视增加音量+");
    }
    @Override
    public void volumeDown() {
        System.out.println("电视降低音量-");
    }
}

 

命令调用 SwitchInvoke

public class SwitchInvoke {
    private Command openCloseCommand;
    private Command verticalCommand;
    private Command horizontalCommand;
    public void bindOpenCloseCommand(Command openCloseCommand) {
        this.openCloseCommand = openCloseCommand;
    }
    // 绑定上下方向键命令
    public void bindVerticalCommand(Command verticalCommand) {
        this.verticalCommand = verticalCommand;
    }
    // 绑定左右方向键命令
    public void bindHorizontalCommand(Command horizontalCommand) {
        this.horizontalCommand = horizontalCommand;
    }
    public void buttonOnClick() {
        System.out.println("按下开机键");
        openCloseCommand.exe();
    }
    public void buttonOffClick() {
        System.out.println("按下关机键");
        openCloseCommand.unexe();
    }
    public void buttonUpClick() {
        System.out.print("按下↑按键……");
        verticalCommand.exe();
    }
    public void buttonDownClick() {
        System.out.print("按下↓按键……");
        verticalCommand.unexe();
    }
    public void buttonLeftClick() {
        System.out.print("按下←按键……");
        horizontalCommand.unexe();
    }
    public void buttonRightClick() {
        System.out.print("单击→按键……");
        horizontalCommand.exe();
    }
}

 

测试:

public class DeviceCommandTest {
    public static void main(String[] args) {
        System.out.println("=========使用遥控器操作电器=========");
        Device bulb = new Bulb();
        Device electricFan = new ElectricFan();
        Device tv = new Television();
        SwitchInvoke switchInvoke = new SwitchInvoke();
        switchInvoke.bindOpenCloseCommand(new OpenCloseCommand(bulb));
        System.out.println("========= 操作电灯 ========");
        switchInvoke.buttonOnClick();
        switchInvoke.buttonOffClick();
        // 绑定 电风扇
        switchInvoke.bindOpenCloseCommand(new OpenCloseCommand(electricFan));
        switchInvoke.bindVerticalCommand(new ChannelCommand(electricFan));
        System.out.println("========= 操作电风扇 ========");
        switchInvoke.buttonOnClick();
        switchInvoke.buttonUpClick();
        switchInvoke.buttonUpClick();
        switchInvoke.buttonDownClick();
        switchInvoke.buttonOffClick();
        //绑定 电视机
        switchInvoke.bindOpenCloseCommand(new OpenCloseCommand(tv));
        switchInvoke.bindVerticalCommand(new ChannelCommand(tv));
        switchInvoke.bindHorizontalCommand(new VolumeCommand(tv));
        System.out.println("========= 操作电视 ========");
        switchInvoke.buttonOnClick();
        switchInvoke.buttonUpClick();
        switchInvoke.buttonUpClick();
        switchInvoke.buttonDownClick();
        switchInvoke.buttonDownClick();
        switchInvoke.buttonRightClick();
        switchInvoke.buttonLeftClick();
        switchInvoke.buttonOffClick();
    }
}

 

结果:

=========使用遥控器操作电器=========

========= 操作电灯 ========

按下开机键

打开电灯

按下关机键

关闭电灯

========= 操作电风扇 ========

按下开机键

打开电风扇,风扇转动。

按下↑按键……加档,风扇加速转动。

按下↑按键……加档,风扇加速转动。

按下↓按键……减档,风扇减速转动。

按下关机键

关闭电风扇,风扇慢慢停止。

========= 操作电视 ========

按下开机键

打开电视,屏幕亮起。

按下↑按键……电视往上换频道+

按下↑按键……电视往上换频道+

按下↓按键……电视往下换频道-

按下↓按键……电视往下换频道-

单击→按键……电视增加音量+

按下←按键……电视降低音量-

按下关机键

关闭电视。

分析

   电灯只有两个动作: 开和关

   电风扇有四个动作: 开、关、加挡和减挡

   电视有六个动作: 开、关、加台、减台、加音量和减音量

  为了让控制器统一处理,不得不先电灯和电风扇空实现不需要的接口。我也没有想到更好的方式去处理。后面想到了,再完善补充。

 

总结:

   命令模式感觉在工作中不常用,但是思想不错。统一控制和切换内容。

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
命令模式和单例模式是两种常见的设计模式,它们在软件工程中都有各自的作用。 **命令模式Command Pattern)**: 命令模式是一种行为设计模式,它封装了请求并使其能被延迟执行。这个模式涉及三个角色: - **抽象命令Command)**:定义了请求的一般接口,包含了执行请求的方法。 - **具体命令(Concrete Command)**:实现了抽象命令,负责具体的执行操作。 - **客户端(Invoker)**:调用命令,不需要关心命令的内部实现。 结合命令模式,你可以创建一组命令对象,每个命令代表一个特定的操作,而客户端通过单例模式获取唯一的命令管理器,从而能够安全、统一地发送和控制这些命令的执行。 **单例模式(Singleton Pattern)**: 单例模式确保了一个类只有一个实例,并提供一个全局访问点。这在资源有限或者需要全局访问点的场景非常有用,比如数据库连接、日志记录等。 当命令模式和单例模式结合时,可能会这样应用: - 创建一个单例的命令管理器,它负责存储所有的命令对象。 - 当客户端需要执行一个操作时,通过这个单例获取命令实例,而不是每次都去创建一个新的。 - 单例模式保证了在整个应用程序生命周期内,命令管理器始终保持唯一,避免了多个实例可能导致的问题。 相关问题: 1. 在什么情况下会考虑使用命令模式和单例模式的结合? 2. 如何确保命令管理器是单例并且在多线程环境下的安全性? 3. 命令模式和工厂模式有什么区别,它们如何共同应用于系统设计?

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天狼1222

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

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

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

打赏作者

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

抵扣说明:

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

余额充值