概述
命令模式把一个请求或者操作封装到一个对象中,目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开。
涉及角色
- 客户端(Client)角色:创建一个具体命令(ConcreteCommand)对象并确定其接收者。
- 命令(Command)角色:声明了一个给所有具体命令类的抽象接口。
- 具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;负责调用接收者的相应操作。
- 请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
- 接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
UML
使用场景
认为是命令的地方都可以使用命令模式
- 发送者和执行者有不同的生命周期
- 需要进行各种管理逻辑
- 需要支持撤消\重做操作
优点
- 降低了系统耦合度,新的命令可以很容易添加到系统中去
- 允许接收请求的一方决定是否要否决请求
- 可以容易地实现对请求的撤销和重做
缺点
使用命令模式可能会导致某些系统有过多的具体命令类
代码示例
以司令员下达命令为例:命令接口,具体命令,司令员,士兵。其中具体命令持有接受者对象,司令员是请求者的角色持有命令对象,士兵是接受者角色
package com.designpattern.command;
public interface Command {
public void beHereNow();
public void runFiveKM(String km);
}
package com.designpattern.command;
public class ConcreteCommand implements Command {
//持有相应的接收者对象
private Receiver receiver = null;
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void beHereNow() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
receiver.gather();
}
@Override
public void runFiveKM(String km) {
receiver.run(km);
}
}
package com.designpattern.command;
public class Commander {
//持有命令对象
private Command command = null;
public Commander(Command command){
this.command = command;
}
public void issueOrders(){
command.beHereNow();
command.runFiveKM("10");
}
}
package com.designpattern.command;
//接收者角色类 士兵或者传令官
public class Receiver {
//真正执行命令相应的操作
public void gather(){
System.out.println("集合……");
}
public void run(String km) {
System.err.println("负重越野…… "+km+"KM");
}
}
package com.designpattern.command;
public class TestMain {
public static void main(String[] args) {
//创建接收者
Receiver receiver = new Receiver();
//创建命令对象,设定它的接收者
Command command = new ConcreteCommand(receiver);
//创建请求者,把命令对象设置进去
Commander invoker = new Commander(command);
//执行方法
invoker.issueOrders();
}
}
运行结果
集合……
负重越野…… 5KM