前言
目前正在出一个设计模式专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~
本节给大家讲一下设计模式中的命令模式,并结合实际业务场景给大家讲解如何使用~
本专题的所有案例代码主要以Java语言为主, 好了, 废话不多说直接开整吧~
命令模式
命令模式(Command Pattern)是一种行为型设计模式,它允许将请求封装成对象,从而使您可以将不同的请求参数化,将请求排队或记录请求日志,以及支持可撤销操作。在这个模式中,请求被封装成一个对象,并在发送者和接收者之间解耦。命令模式允许在不更改现有客户端代码的情况下添加新命令。
命令模式通常包括以下几个角色:
Command(命令):定义了执行操作的接口。ConcreteCommand(具体命令):实现了Command接口并定义了具体的操作。Invoker(调用者):发出请求的对象,它不知道具体执行的操作。Receiver(接收者):执行操作的对象。
// 定义一个命令接口
public interface Command {
void execute();
}
// 定义具体的命令类
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}
// 定义接收者类
public class Light {
public void turnOn() {
System.out.println("Light is on");
}
public void turnOff() {
System.out.println("Light is off");
}
}
// 定义调用者类
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建接收者对象
Light light = new Light();
// 创建具体命令对象并设置其接收者
Command lightOnCommand = new LightOnCommand(light);
// 创建调用者对象并设置其命令
RemoteControl remoteControl = new RemoteControl();
remoteControl.setCommand(lightOnCommand);
// 调用者发出请求,命令对象执行具体操作
remoteControl.pressButton();
}
}
在上面的示例中,LightOnCommand类是具体的命令类,它实现了Command接口,并将具体的操作(即打开灯)封装在execute()方法中。Light类是接收者类,它包含了打开和关闭灯的方法。RemoteControl类是调用者类,它发出请求并执行命令。Client类是客户端代码,它使用这些类来演示命令模式的使用。
最佳实践
电商平台在订单处理过程中可以使用命令模式,将订单操作封装成命令对象,从而实现请求的排队、记录日志以及支持撤销操作等功能。
以下是一个简单的电商平台订单处理系统的命令模式示例:
// 定义一个命令接口
public interface OrderCommand {
void execute();
void undo();
}
// 定义具体的命令类,比如创建订单、取消订单、支付订单等
public class CreateOrderCommand implements OrderCommand {
private Order order;
public CreateOrderCommand(Order order) {
this.order = order;
}
public void execute() {
order.create();
}
public void undo() {
order.cancelCreate();
}
}
public class CancelOrderCommand implements OrderCommand {
private Order order;
public CancelOrderCommand(Order order) {
this.order = order;
}
public void execute() {
order.cancel();
}
public void undo() {
order.uncancel();
}
}
public class PayOrderCommand implements OrderCommand {
private Order order;
public PayOrderCommand(Order order) {
this.order = order;
}
public void execute() {
order.pay();
}
public void undo() {
order.unpay();
}
}
// 定义接收者类,即订单类
public class Order {
private int orderId;
private String status;
public void create() {
System.out.println("订单创建成功");
this.status = "Created";
}
public void cancelCreate() {
System.out.println("取消订单创建");
this.status = "";
}
public void cancel() {
System.out.println("订单取消成功");
this.status = "Cancelled";
}
public void uncancel() {
System.out.println("订单取消被撤销");
this.status = "Created";
}
public void pay() {
System.out.println("订单支付成功");
this.status = "Paid";
}
public void unpay() {
System.out.println("订单支付被撤销");
this.status = "Created";
}
public String getStatus() {
return status;
}
}
// 定义调用者类,即订单处理器类
public class OrderProcessor {
private List<OrderCommand> commandList = new ArrayList<>();
public void addCommand(OrderCommand command) {
commandList.add(command);
}
public void processCommands() {
for (OrderCommand command : commandList) {
command.execute();
}
commandList.clear();
}
public void undoLastCommand() {
if (commandList.size() > 0) {
OrderCommand lastCommand = commandList.get(commandList.size() - 1);
lastCommand.undo();
commandList.remove(lastCommand);
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建订单对象
Order order = new Order();
// 创建具体命令对象并设置其接收者
OrderCommand createOrderCommand = new CreateOrderCommand(order);
OrderCommand cancelOrderCommand = new CancelOrderCommand(order);
OrderCommand payOrderCommand = new PayOrderCommand(order);
// 创建订单处理器对象并设置其命令
OrderProcessor orderProcessor = new OrderProcessor();
orderProcessor.addCommand(createOrderCommand);
orderProcessor.addCommand(cancelOrderCommand);
orderProcessor.addCommand(payOrderCommand
// 处理命令
orderProcessor.processCommands();
// 输出订单状态
System.out.println("订单状态: " + order.getStatus());
// 撤销最后一个命令
orderProcessor.undoLastCommand();
// 输出订单状态
System.out.println("撤销后订单状态: " + order.getStatus());
}
}
输出:
订单创建成功
订单取消成功
订单支付成功
订单状态: Paid
撤销后订单状态: Paid
在这个示例中,订单处理器类 OrderProcessor 充当了调用者角色,将具体的订单操作命令 OrderCommand 对象添加到一个命令列表中,并在需要的时候执行它们。同时,OrderProcessor 类还提供了一个 undoLastCommand() 方法,用于撤销最后一个执行的命令。
具体的订单操作命令实现了 OrderCommand 接口,并将订单对象 Order 设置为它们的接收者。当执行命令时,相应的操作将在订单对象中被执行,比如 CreateOrderCommand 将调用 Order 对象的 create() 方法, CancelOrderCommand 将调用 Order 对象的 cancel() 方法等等。
通过使用命令模式,我们可以很方便地实现对订单操作的排队、记录日志以及支持撤销操作等功能,而无需修改订单对象的代码。同时,通过将订单操作封装成命令对象,我们也可以很容易地扩展订单处理系统,添加新的订单操作命令。
结束语
设计模式其实并不难,大家在学习的时候一定要在理解的基础上去写代码,不要去背代码。下节给大家讲解释器模式~
本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~
相关文章
- 一起来学设计模式之认识设计模式
- 一起来学设计模式之单例模式
- 一起来学设计模式之工厂模式
- 一起来学设计模式之建造者模式
- 一起来学设计模式之原型模式
- 一起来学设计模式之适配器模式
- 一起来学设计模式之桥接模式
- 一起来学设计模式之组合模式
- 一起来学设计模式之装饰器模式
- 一起来学设计模式之外观模式
- 一起来学设计模式之享元模式
- 一起来学设计模式之代理模式
- 一起来学设计模式之责任链模式
项目源码(源码已更新 欢迎star⭐️)
Kafka 专题学习
- 一起来学kafka之Kafka集群搭建
- 一起来学kafka之整合SpringBoot基本使用
- 一起来学kafka之整合SpringBoot深入使用(一)
- 一起来学kafka之整合SpringBoot深入使用(二)
- 一起来学kafka之整合SpringBoot深入使用(三)
项目源码(源码已更新 欢迎star⭐️)
ElasticSearch 专题学习
项目源码(源码已更新 欢迎star⭐️)
往期并发编程内容推荐
- Java多线程专题之线程与进程概述
- Java多线程专题之线程类和接口入门
- Java多线程专题之进阶学习Thread(含源码分析)
- Java多线程专题之Callable、Future与FutureTask(含源码分析)
- 面试官: 有了解过线程组和线程优先级吗
- 面试官: 说一下线程的生命周期过程
- 面试官: 说一下线程间的通信
- 面试官: 说一下Java的共享内存模型
- 面试官: 有了解过指令重排吗,什么是happens-before
- 面试官: 有了解过volatile关键字吗 说说看
- 面试官: 有了解过Synchronized吗 说说看
- Java多线程专题之Lock锁的使用
- 面试官: 有了解过ReentrantLock的底层实现吗?说说看
- 面试官: 有了解过CAS和原子操作吗?说说看
- Java多线程专题之线程池的基本使用
- 面试官: 有了解过线程池的工作原理吗?说说看
- 面试官: 线程池是如何做到线程复用的?有了解过吗,说说看
- 面试官: 阻塞队列有了解过吗?说说看
- 面试官: 阻塞队列的底层实现有了解过吗? 说说看
- 面试官: 同步容器和并发容器有用过吗? 说说看
- 面试官: CopyOnWrite容器有了解过吗? 说说看
- 面试官: Semaphore在项目中有使用过吗?说说看(源码剖析)
- 面试官: Exchanger在项目中有使用过吗?说说看(源码剖析)
- 面试官: CountDownLatch有了解过吗?说说看(源码剖析)
- 面试官: CyclicBarrier有了解过吗?说说看(源码剖析)
- 面试官: Phaser有了解过吗?说说看
- 面试官: Fork/Join 有了解过吗?说说看(含源码分析)
- 面试官: Stream并行流有了解过吗?说说看