😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
什么是命令模式
命令模式(Command Pattern)是一种行为设计模式,它将请求封装成一个对象,从而使发送者和接收者解耦。在命令模式中,将请求的发送者与具体执行请求的接收者分离,通过将请求封装成命令对象,发送者只需通过调用命令对象的执行方法来发起请求,而无需关心请求的具体执行细节和接收者。
命令模式类图
命令模式色其职责
Command
:抽象命令一般定义为接口,用来定义执行命令的接口
ConcreteCommand
:具体命令,通常会持有接收者对象,并调用接收者对象的相应功能来完成命令要执行的操作
Receiver
:命令接收者,也就是命令真正的执行者
Invoker
:调用者,通过它来调用命令
Client
:客户端,可以设置命令与命令的接收者
命令模式适用场景
- 需要将请求发送者和请求接收者解耦的场景
- 需要支持撤销、重做等操作的场景
- 需要支持事务操作的场景
- 需要支持日志记录、回滚等操作的场景
- 需要支持命令的队列、延迟执行等特性的场景
命令模式可以用于各种场景,比如电商平台的订单处理系统,可以将不同的订单操作封装成具体的命令对象,发送者只需通过调用命令对象的执行方法来处理订单,而无需直接操作订单对象。这样可以实现订单操作的灵活性和可扩展性,同时也方便了订单操作的撤销、重做等功能的实现。
生活案例
假设我们有一个智能家居系统,其中包括灯光控制、音响控制和窗帘控制等功能。我们可以使用命令模式来实现对这些设备的控制。
比如,当我们想要打开客厅的灯时,只需按下遥控器上的 “灯光开” 按钮,遥控器会调用 LightOnCommand
的 execute()
方法,从而控制灯光打开。同样,当我们想要关闭窗帘时,只需按下遥控器上的 “窗帘关” 按钮,遥控器会调用CurtainCloseCommand
的 execute()
方法,从而控制窗帘关闭。
通过使用命令模式,我们实现了请求的发送者(遥控器)和请求的接收者(具体的命令对象)之间的解耦。遥控器只需关心按钮与命令的绑定,而不需要关心具体的命令执行细节和设备对象。这样可以提高系统的灵活性和可扩展性,并支持一些额外的功能,如撤销操作、记录日志等。
案例代码
下面是使用 代码描述上述智能家居控制场景的示例:
首先,我们需要定义抽象命令类 Command
:
public interface Command {
void execute();
}
接着我们创建具体的设备类,比如 Light
、Audio
、Curtain
:
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");
}
}
然后,我们创建具体的命令类,比如 LightOnCommand
、LightOffCommand
、AudioPlayCommand
、AudioStopCommand
、CurtainOpenCommand
、CurtainCloseCommand
这里我们为了减少代码量 就简单书写两个 LightOnCommand
、LightOffCommand
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() 方法,从而控制相应的设备执行对应的操作
最终运行效果:
命令模式优缺点
命令模式的优点:
- 解耦请求发送者和接收者:命令模式通过将请求封装成命令对象,使得请求发送者和接收者之间解耦。发送者不需要知道具体的接收者和执行细节,只需通过命令对象发送请求即可。
- 容易扩展和修改:由于命令模式将请求与具体的操作绑定在一起,新增或修改命令类很容易,不会影响其他部分的代码。可以方便地添加新的命令和对应的操作。
- 支持撤销和重做:命令对象可以记录操作的状态和参数,使得可以很容易地实现撤销和重做功能。
- 支持队列操作:命令对象可以存储在队列中,支持延迟执行、排队执行和异步执行。
命令模式的缺点:
- 代码复杂性增加:引入了额外的命令类和接口,增加了代码的复杂性。
- 类膨胀:每个具体命令都需要创建一个具体命令类,当命令过多时,类的数量会增加。
- 运行效率降低:因为命令模式将请求封装成对象,需要额外的开销来创建和管理命令对象。
总体而言,命令模式适用于需要将请求发送者和接收者解耦的情况,以及需要支持撤销、重做、队列操作等功能的场景。然而,如果命令的数量庞大或者需要高效的执行速度,可能会带来一定的复杂性和性能开销。在实际应用中,需要根据具体的需求和情况进行权衡和选择。
结语
本章节主要介绍了命令模式、命令模式适用场景、命令模式的优缺点,并以智能家居系统举例模拟命令模式的使用方法,如果本文对你有用,欢迎关注收藏评论,后续将陆续推出贴切生活的搞笑讲解方式带大家一起学编程~