命令模式简介
- 命令模式(command pattern)也叫动作模式或者事务模式。它是将请求(命令)封装成对象,使得可以用不同的请求对客户端进行参数化,具体的请求可以在运行时更改、排队和记录,它将发出者和 接收者解耦,顺序是: 发出者 --> 命令 --> 接收者。
- 实际使用:Spring JdbcTemplate 中的execute/query方法、Runnable Thread start()。
结构
- 1.抽象命令(Abstract Command): 抽象命令是一个接口,定义了执行操作的统一方法。具体的命令类会实现这个接口,并提供执行相应操作的具体逻辑
- 2.具体命令(Concrete Command):具体命令类实现了抽象命令类,它拥有 接收者对象 ,并通过调用接收者的功能来完成命令要执行的操作。
- 3.接收者(Receiver): 执行实际命令的类,命令对象会调用接收者的方法来执行请求。
- 4.调用者(Invoker):持有命令对象,通常是多个,并通过访问命令对象来执行相关请求,他不直接访问接收者。
UML图
具体实现
例子:餐厅中,服务员(Waiter)点菜,然后厨师(Chef)做菜。
UML图
代码实现
- 抽象命令类
package com.xxliao.pattern.behavioral.command.demo;
/**
* @author xxliao
* @description: 抽象命令类接口,定义了执行操作的统一方法
* @date 2024/5/25 19:26
*/
public interface Command {
// 点菜
void order();
// 取消点菜
void cancelOrder();
}
- 具体命令类
package com.xxliao.pattern.behavioral.command.demo;
/**
* @author xxliao
* @description: 具体命令类,实现了抽象命令接口,通过组合,拥有接收者对象,并通过调用接收者对象的方法来完成命令要执行的操作。
* @date 2024/5/25 19:30
*/
public class OrderCommand implements Command {
// 聚合方式 持有 接收者对象
private Chef chef;
public OrderCommand(Chef chef) {
this.chef = chef;
}
@Override
public void order() {
chef.cook();
}
@Override
public void cancelOrder() {
chef.cancelCooking();
}
}
- 接受者类
package com.xxliao.pattern.behavioral.command.demo;
/**
* @author xxliao
* @description: 接收者类,执行实际命令的类,命令对象会调用接收者的方法来执行请求
* @date 2024/5/25 19:28
*/
public class Chef {
public void cook() {
System.out.println("chef process order。。。");
}
public void cancelCooking() {
System.out.println("chef cancel cooking...");
}
}
- 调用者类
package com.xxliao.pattern.behavioral.command.demo;
/**
* @author xxliao
* @description: 调用者类 - 持有命令对象,通常是多个,并通过访问命令对象来执行相关请求,他不直接访问接收者。
* @date 2024/5/25 22:40
*/
public class Waiter {
// 持有命令对象
private Command command;
public void setCommand(Command command) {
this.command = command;
}
/**
* @description 点餐
* @author xxliao
* @date 2024/5/25 22:45
*/
public void takeOrder() {
// 服务员收到顾客(客户端)点餐请求
System.out.println("服务员收到顾客(客户端)点餐请求");
// 执行点餐操作,使用命令对象,实际是具体命令对象去执行,然后调用的是接收者对象Chef相关的执行方法。
command.order();
}
/**
* @description 取消点餐
* @author xxliao
* @date 2024/5/25 22:46
*/
public void cancelOrder() {
// 服务员收到顾客(客户端)取消点餐请求
System.out.println("服务员收到顾客(客户端)取消点餐请求");
// 执行取消点餐操作,使用命令对象,实际是具体命令对象去执行,然后调用的是接收者对象Chef相关的执行方法。
command.cancelOrder();
}
}
- 测试客户端
package com.xxliao.pattern.behavioral.command.demo;
/**
* @author xxliao
* @description: 命令模式 测试客户端
* @date 2024/5/25 22:47
*/
public class Client {
public static void main(String[] args) {
// 创建接收者对象 -- 厨师对象
Chef chef = new Chef();
// 创建具体命令对象, 然后将接收者对象 当作参数 传入
Command orderCommand = new OrderCommand(chef);
// 创建调用者对象 -- 服务员
Waiter waiter = new Waiter();
// 将具体命令对象 传入 调用者对象
waiter.setCommand(orderCommand);
// 执行相关操作
waiter.takeOrder();
waiter.cancelOrder();
}
}
- 测试结果