👉文章示例代码👈
定义
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
四个角色
命令模式主要有以下四个角色:
- 抽象命令类Command:声明执行操作的接口。
- 具体命令类Concrete Command:是抽象命令类的具体实现类,持有接受者对象,同时通过调用接收者的功能来完成命令要执行的操作。
- 接收者Receiver:执行命令功能的相关操作。
- 调用者Invoker:拥有很多命令对象,并通过访问命令对象来执行相关请求,其不直接访问接收者。
场景示例
笔者女朋友在一家知识付费公司做人事兼老板助理,常常会接收到一些来自老板的工作安排。
笔者这里以此为例。假设这天下班,女朋友接到老板的以下几个工作安排:
- 明早9点准时在公司公号上发布一篇xx的推文。
- 上午和老板一起外出看讲座场地。
- 安排明天下午两点的会议。
创建抽象命令类
1 2 3 4 5 6 7 8 9 10 11 12
|
public interface Command {
void execute(); }
|
创建具体命令类
每一个具体的工作安排对应一个具体的命令类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
public class SendTweetsCommand implements Command {
private Staff staff;
public SendTweetsCommand(Staff staff) { this.staff = staff; }
public void execute() { staff.sendTweets(); } }
public class LookVenueCommand implements Command {
private Staff staff;
public LookVenueCommand(Staff staff) { this.staff = staff; }
public void execute() { staff.lookVenue(); } }
public class AttendMeetingCommand implements Command {
private Staff staff;
public AttendMeetingCommand(Staff staff) { this.staff = staff; }
public void execute() { staff.attendMeeting(); } }
|
创建接受者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class Staff {
private String name;
public Staff(String name) { this.name = name; }
public void sendTweets() { System.out.println(this.name + "早上9点准时在公司公号上发布一篇xx的推文"); }
public void lookVenue() { System.out.println(this.name + "上午和老板一起外出看讲座场地"); }
public void attendMeeting() { System.out.println(this.name + "安排下午两点的会议"); } }
|
创建调用者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
public class Boss {
private List<Command> commandList = new ArrayList<Command>();
public void addCommand(Command command) { commandList.add(command); }
public void sendCommands() { for (Command command : commandList) { command.execute(); } commandList.clear(); } }
|
测试类及输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class Test {
public static void main(String[] args) { Staff staff = new Staff("亚萍"); Command sendTweetsCommand = new SendTweetsCommand(staff); Command lookVenueCommand = new LookVenueCommand(staff); Command attendMeetingCommand = new AttendMeetingCommand(staff);
Boss boss = new Boss(); boss.addCommand(sendTweetsCommand); boss.addCommand(lookVenueCommand); boss.addCommand(attendMeetingCommand);
boss.sendCommands(); } }
|
测试类的输出结果如下:
亚萍早上9点准时在公司公号上发布一篇xx的推文
亚萍上午和老板一起外出看讲座场地
亚萍安排下午两点的会议
类结构图
以上示例类的结构图如下所示

总结
适用场景
- 当请求调用者和请求接受者需要解耦时,命令模式使得调用者和接受者不直接交互。
- 需要抽象出等待执行的行为。
优点
- 降低系统的耦合度。
- 良好的扩展性。新增或者删除命令不会影响其他类。
缺点
对于每一个具体的操作都需要对应设计一个具体的命令类,这会导致类的数目的增加,增加系统的复杂性。
参考