Java设计模式—命令模式(Command Pattern)

本文介绍了如何运用命令模式来实现一个手机app控制多种智能家电的功能。通过创建不同的命令类,每个命令对应家电的一个特定操作,实现了请求者(手机app)与执行者(家电)的解耦。在代码实现中,展示了如何创建接收者、命令接口、具体命令类以及遥控器类,并提供了撤销操作。这种模式使得系统更易于扩展,但也会增加类的数量,提高复杂度。
摘要由CSDN通过智能技术生成

命令模式

业务需求

  • 智能生活项目需求
  • 有一套只能家电,有照明灯,风扇,冰箱,洗衣机,我们只需要手机安装app即可控制这些家电
  • 这些智能家电来自不同的厂家,不想每个家电都安装app分别控制,希望只安装一个app就可以控制全部智能家电
  • 要实现一个app控制所有只能家电的需要,需要每个只能家电提供一个统一的接口调用,适合使用命令模式
  • 命令模式可以将动作的请求者,从动作的执行者对象汇总解耦出来
  • 本例中,动作请求者是手机app,都做执行者是每个厂商的一个家电产品

基本介绍

  • 命令模式,在设计软件中,我们经常需要向某些对象发送请求,但是不知道具体请求接收是谁,也不知道被请求操作的是哪个;只需在程序运行时指定具体的接受者即可,使用命令模式设计
  • 命令模式使请求发送者与请求接受者消除彼此耦合,让对象之间调用关系更加灵活
  • 在命令模式中,会将一个请求封装为一个对象,便于使用不同参数来表示不同请求,命令模式也支持撤销操作
  • 通俗理解,长官发出命令,士兵去执行;长官是调用者Invoke,士兵是接受者Receiver,MyCommond是命令,实现了Commond接口,持有接收对象

原理类图
在这里插入图片描述
原理类图说明

  • Invoker:调用者角色
  • Command:命令角色,包含需要执行的所有命令,可以是接口或抽象类
  • Receiver:接收者角色,知道如何实施和执行一个请求相关操作
  • ConcreteCommand:将一个接收者对象和一个动作绑定,调用接收者相应的操作,实现excute

代码实现
在这里插入图片描述
定义接收者,具体执行功能

public class LightReceiver {
    public void on() {
        System.out.println("电灯打开了...");
    }
    public void off() {
        System.out.println("电灯关闭了...");
    }
}

命令接口

/ 命令接口
public interface Command {
    // 执行动作
    public void excute();
    // 撤销动作
    public void undo();
}

开命令

public class LightOnCommand implements Command {
    //聚合LightReceiver
    LightReceiver light;
    // 构造
    public LightOnCommand(LightReceiver light) {
        this.light = light;
    }
    @Override
    public void excute() {
        light.on();
    }
    @Override
    public void undo() {
        light.off();
    }
}

关命令

public class LightOffCommand implements Command {
    //聚合LightReceiver
    LightReceiver light;
    // 构造
    public LightOffCommand(LightReceiver light) {
        this.light = light;
    }
    @Override
    public void excute() {
        light.off();
    }
    @Override
    public void undo() {
        light.on();
    }
}

空命令

// 空执行,用于初始化
public class NoCommand implements Command{
    @Override
    public void excute() {
        // 空操作
    }
    @Override
    public void undo() {
        // 空操作
    }
}

遥控器,整合接收者和命令

public class RemoteController {
    //开 按钮命令组
    Command[] onCommands;
    Command[] offCommands;
    // 记住最近的一次操作,用于撤销
    Command undoCommand;
    // 构造器,完成按钮初始化
    public RemoteController() {
        onCommands = new Command[5];
        offCommands = new Command[5];
        // 用空操作初始化
        for (int i=0; i<5;i++) {
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
    }
    // 设置需要的命令
    public void setCommand(int no, Command onCommand, Command offCommand) {
        onCommands[no] = onCommand;
        offCommands[no] = offCommand;
    }
    // 按下开按钮
    public void onButtonWasPushed(int no) {
        // 找到对应按钮,调用对应方法
        onCommands[no].excute();
        // 记录这次操作,用于撤销
        undoCommand = onCommands[no];
    }
    // 按下关按钮
    public void offButtonWashPushed(int no) {
        offCommands[no].excute();
        undoCommand = offCommands[no];
    }
    // 按下撤销按钮
    public void undoButtonWasPushed() {
        undoCommand.undo();
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        // 接收者
        LightReceiver lightReceiver = new LightReceiver();
        // 开关命令
        LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
        LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
        // 遥控器
        RemoteController remoteController = new RemoteController();
        // 设置命令
        remoteController.setCommand(0, lightOnCommand, lightOffCommand);

        System.out.println("按下开灯按钮===============");
        remoteController.onButtonWasPushed(0);
        System.out.println("按下关灯按钮===============");
        remoteController.onButtonWasPushed(0);
        System.out.println("撤销=====================");
        remoteController.undoButtonWasPushed();
    }
}

在这里插入图片描述
说明

  • 如果扩展新的功能,需要新增新的接收者、开命令、关命令;
  • 空命令可以保存最近的一次命令,方便随时撤销最近的命令,也就是执行最近命令的相反命令
  • 结构略复杂,实质就是命令类聚合了接收者,遥控器聚合了命令类

Spring源码分析—JdbcTemplate

命令模式注意事项

  • 将发请求的对象和执行请求的对象解耦;命令对象负责纽带桥梁作用,请求发起者和请求执行者之间的解耦通过命令对象实现
  • 容易设计一个命令队列,把命令放到队列中,可以多线程执行命令
  • 容易实现对请求的撤销和重做
  • 命令模式不足,造成系统有过多的类,增加系统复杂度
  • 空命令也是一种设计模式,为我们省去了判断空的操作;如果没有空命令,可能每按下按键都要判断空,造成编码麻烦
  • 命令模式经典应用场景,界面的一个个按钮命令,模拟CMD订单的撤销/回复,触发-反馈机制
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值