津津乐道设计模式 - 命令模式详解(以智能家居系统举例带你了解命令模式)

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

什么是命令模式

命令模式(Command Pattern)是一种行为设计模式,它将请求封装成一个对象,从而使发送者和接收者解耦。在命令模式中,将请求的发送者与具体执行请求的接收者分离,通过将请求封装成命令对象,发送者只需通过调用命令对象的执行方法来发起请求,而无需关心请求的具体执行细节和接收者。

命令模式类图
在这里插入图片描述
命令模式色其职责

Command:抽象命令一般定义为接口,用来定义执行命令的接口
ConcreteCommand:具体命令,通常会持有接收者对象,并调用接收者对象的相应功能来完成命令要执行的操作
Receiver:命令接收者,也就是命令真正的执行者
Invoker:调用者,通过它来调用命令
Client:客户端,可以设置命令与命令的接收者

命令模式适用场景

  • 需要将请求发送者和请求接收者解耦的场景
  • 需要支持撤销、重做等操作的场景
  • 需要支持事务操作的场景
  • 需要支持日志记录、回滚等操作的场景
  • 需要支持命令的队列、延迟执行等特性的场景

命令模式可以用于各种场景,比如电商平台的订单处理系统,可以将不同的订单操作封装成具体的命令对象,发送者只需通过调用命令对象的执行方法来处理订单,而无需直接操作订单对象。这样可以实现订单操作的灵活性和可扩展性,同时也方便了订单操作的撤销、重做等功能的实现。

生活案例

假设我们有一个智能家居系统,其中包括灯光控制、音响控制和窗帘控制等功能。我们可以使用命令模式来实现对这些设备的控制。

在这里插入图片描述

比如,当我们想要打开客厅的灯时,只需按下遥控器上的 “灯光开” 按钮,遥控器会调用 LightOnCommandexecute()方法,从而控制灯光打开。同样,当我们想要关闭窗帘时,只需按下遥控器上的 “窗帘关” 按钮,遥控器会调用CurtainCloseCommandexecute()方法,从而控制窗帘关闭。

通过使用命令模式,我们实现了请求的发送者(遥控器)和请求的接收者(具体的命令对象)之间的解耦。遥控器只需关心按钮与命令的绑定,而不需要关心具体的命令执行细节和设备对象。这样可以提高系统的灵活性和可扩展性,并支持一些额外的功能,如撤销操作、记录日志等。

案例代码

下面是使用 代码描述上述智能家居控制场景的示例:

首先,我们需要定义抽象命令类 Command

public interface Command {
    void execute();
}

接着我们创建具体的设备类,比如 LightAudioCurtain

public class Light {
    public void turnOn() {
        System.out.println("Light is on");
    }

    public void turnOff() {
        System.out.println("Light is off");
    }
}

public class Audio {
    public void play() {
        System.out.println("Audio is playing");
    }

    public void stop() {
        System.out.println("Audio is stopped");
    }
}

public class Curtain {
    public void open() {
        System.out.println("Curtain is open");
    }

    public void close() {
        System.out.println("Curtain is closed");
    }
}

然后,我们创建具体的命令类,比如 LightOnCommandLightOffCommandAudioPlayCommandAudioStopCommandCurtainOpenCommandCurtainCloseCommand

这里我们为了减少代码量 就简单书写两个 LightOnCommandLightOffCommand

public class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOn();
    }
}

public class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOff();
    }
}

// 同样的方式创建其他命令类...这里省略

接下来,我们需要创建遥控器类 RemoteController

public class RemoteController {
    private Map<String, Command> commands;

    public RemoteController() {
        commands = new HashMap<>();
    }

    public void setCommand(String button, Command command) {
        commands.put(button, command);
    }

    public void pressButton(String button) {
        if (commands.containsKey(button)) {
            Command command = commands.get(button);
            command.execute();
        } else {
            System.out.println("Button not found!");
        }
    }
}

现在,我们可以在主程序中使用这些类来模拟智能家居控制:

public class CommandPatternest {
    public static void main(String[] args) {
        // 创建设备对象
        Light livingRoomLight = new Light();

        // 创建命令对象
        Command lightOnCommand = new LightOnCommand(livingRoomLight);
        Command lightOffCommand = new LightOffCommand(livingRoomLight);

        // 创建遥控器
        RemoteController remoteController = new RemoteController();

        // 设置命令和按钮对应关系
        remoteController.setCommand("Button 1", lightOnCommand);
        remoteController.setCommand("Button 2", lightOffCommand);

        // 模拟按下按钮
        remoteController.pressButton("Button 1"); // Light On
        remoteController.pressButton("Button 2"); // Light Off
    }
}

整体代码结构如下:

在这里插入图片描述

以上代码实现了一个简单的智能家居控制系统,通过命令模式实现了遥控器与设备之间的解耦。根据按下的按钮,遥控器会调用对应命令的 execute() 方法,从而控制相应的设备执行对应的操作

最终运行效果:

在这里插入图片描述

命令模式优缺点

命令模式的优点:

  • 解耦请求发送者和接收者:命令模式通过将请求封装成命令对象,使得请求发送者和接收者之间解耦。发送者不需要知道具体的接收者和执行细节,只需通过命令对象发送请求即可。
  • 容易扩展和修改:由于命令模式将请求与具体的操作绑定在一起,新增或修改命令类很容易,不会影响其他部分的代码。可以方便地添加新的命令和对应的操作。
  • 支持撤销和重做:命令对象可以记录操作的状态和参数,使得可以很容易地实现撤销和重做功能。
  • 支持队列操作:命令对象可以存储在队列中,支持延迟执行、排队执行和异步执行。

命令模式的缺点:

  • 代码复杂性增加:引入了额外的命令类和接口,增加了代码的复杂性。
  • 类膨胀:每个具体命令都需要创建一个具体命令类,当命令过多时,类的数量会增加。
  • 运行效率降低:因为命令模式将请求封装成对象,需要额外的开销来创建和管理命令对象。

总体而言,命令模式适用于需要将请求发送者和接收者解耦的情况,以及需要支持撤销、重做、队列操作等功能的场景。然而,如果命令的数量庞大或者需要高效的执行速度,可能会带来一定的复杂性和性能开销。在实际应用中,需要根据具体的需求和情况进行权衡和选择。

结语

本章节主要介绍了命令模式、命令模式适用场景、命令模式的优缺点,并以智能家居系统举例模拟命令模式的使用方法,如果本文对你有用,欢迎关注收藏评论,后续将陆续推出贴切生活的搞笑讲解方式带大家一起学编程~

样例代码:https://github.com/lhmyy521125/toher-designmode

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Micro麦可乐

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

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

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

打赏作者

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

抵扣说明:

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

余额充值