命令模式 (学习笔记2021.07.15)

命令模式(学习笔记2021.07.15)

前言:

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

**意图:**将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。 (解耦)

**主要解决:**在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

前提条件

设计一个家电自动化遥控器的API。

这个遥控器具有七个可编程的插槽(每个都可以指定到一个不同的家电装置),每个插槽都有对应的开关按钮。这个遥控器还具备一个整体的撤销按钮, 我也在光盘里附上一组Java类,

这些类是由多家厂商开发出来的,用来控制家电自动化装置,例如电灯、风扇、热水器、音响设备和其他类似的可控制装置。希望你能够创建一组控制遥控器的API,让每个插槽都能够控制一个或一组装置。

请注意,能够控制目前的装置和任何未来可能出现的装置,这一点是很重要的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ulQB1Ef-1626279516630)(https://z3.ax1x.com/2021/07/14/WZB4d1.md.jpg)]

命令模式解决

命令模式的简单介绍

从餐厅来介绍:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0lEtFYuv-1626279516632)(https://z3.ax1x.com/2021/07/14/WZsDII.md.jpg)]

从图上可以看出, 顾客的任务是将自己需要什么食品写到订单上,

而服务员也不关心顾客点的是什么, 找那个厨师, 只是将订单传递放在订单柜台, 然后通知来新订单了,

对应厨师根据订单内容, 开始制作食品, 并输出出来。

从而达到了顾客、厨师的解耦, 相互都不关注与不知道是谁来接任务。

使用命令模式解决遥控器

1.1 创建命令接口

(也就是餐厅的服务员)

/**
 * @Author: ZhiHao
 * @Date: 2021/7/14 17:34
 * @Description: 命令基接口 (所有需要执行命令的实现该接口)
 * @Versions 1.0
 **/
public interface CommandBase {
     /**
     * 执行打开命令
     *
     * @author: ZhiHao
     * @date: 2021/7/14
     */
    void executeOpen();
    /**
     * 执行关闭命令
     *
     * @author: ZhiHao
     * @date: 2021/7/14
     */
    void executeStop();
}
1.2 创建电灯、风扇、命令实现

(真正执行命令的餐厅厨师是里面构建方法厂家提供的驱动对象-请求类)

/**
 * @Author: ZhiHao
 * @Date: 2021/7/14 17:42
 * @Description: 风扇控制
 * @Versions 1.0
 **/
public class Blower implements CommandBase{

    private String 厂家提供的对象;
    
    public Blower(String 厂家提供的对象) {
        this.厂家提供的对象 = 厂家提供的对象;
    }

    @Override
    public void executeOpen() {
        System.out.println(厂家提供的对象+"执行了打开命令动作");
    }

    @Override
    public void executeStop() {
        System.out.println(厂家提供的对象+"执行了打开命令动作");
    }
}
//  ---------------------电灯一样的代码--------------------------
1.3 创建遥控器

(也就是餐厅顾客调用者)

/**
 * @Author: ZhiHao
 * @Date: 2021/7/14 19:53
 * @Description: 遥控器
 * @Versions 1.0
 **/
public class RemoteControl {

    private final List<CommandBase> commandBase = new ArrayList<>();

    /**
     * 添加需要执行一系列宏命令
     *
     * @param commandBase
     * @author: ZhiHao
     * @date: 2021/7/14
     */
    public void addCommandBase(CommandBase... commandBase) {
        Optional.ofNullable(commandBase).map(Arrays::asList).ifPresent(this.commandBase::addAll);
    }

    public void addCommandOneBase(int index,CommandBase commandBase) {
        Optional.ofNullable(commandBase).ifPresent(base-> this.commandBase.add(index,base));
    }

    /** 
     * 批量执行一系列宏命令
     *   
     * @author: ZhiHao
     * @date: 2021/7/14 
     */
    public void MacroCommandOpen(){
        commandBase.forEach(CommandBase::executeOpen);
    }

    /** 
     * 执行单个命令
     * 
     * @param index  
     * @author: ZhiHao
     * @date: 2021/7/14 
     */
    public void open(int index){
        commandBase.get(index).executeOpen();
    }
    public void MacroCommandStop(){
        commandBase.forEach(CommandBase::executeOpen);
    }

    public void stop(int index){
        commandBase.get(index).executeStop();
    }
}
1.4 进行测试
@Test
    public void applicationTest() throws Exception {
        // 请求类
        String electricLight = "电灯厂家提供的驱动对象";
        String blower = "风扇厂家提供的驱动对象";
       // 创建遥控器(顾客)
        RemoteControl control = new RemoteControl();
        // 创建命令 (订单), 电灯厂家提供的驱动对象才是真正执行请求的对象
        CommandBase commandBase1 = new ElectricLight(electricLight);
        CommandBase commandBase2 = new Blower(blower);
        // 遥控器添加命令
        control.addCommandOneBase(0,commandBase1);
        control.addCommandOneBase(1,commandBase2);
        // 执行打开命令, 会将命令传给调用者 (厨师)
        control.open(0);
        control.open(1);
        control.stop(0);
    }
// ----------------
电灯厂家提供的驱动对象执行了打开命令动作
风扇厂家提供的驱动对象执行了打开命令动作
电灯厂家提供的驱动对象执行了关闭命令动作

// 创建遥控器(顾客)
RemoteControl control = new RemoteControl();
// 创建命令, 电灯厂家提供的驱动对象才是真正执行请求的对象
CommandBase commandBase1 = new ElectricLight(electricLight);
CommandBase commandBase2 = new Blower(blower);
// 添加一系列宏命令
control.addCommandBase(commandBase1,commandBase2);
// 并执行
control.MacroCommandOpen();    

定义:

命令模式将 “请求(命令)”封装成对象,以便使用不同的请求、 队列或者日志来参数化其他对象.命令模式也支持可撤销的操作.

当需要将发出请求的对象和执行请求的对象解耦的时候,使用命令模式。
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、付费专栏及课程。

余额充值