相信自己,请一定要相信自己
上一章简单介绍了模板模式(十六), 如果没有看过, 请观看上一章
一. 命令模式
定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,
这样方便将命令对象进行储存、传递、调用、增加与管理。
意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,
比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。
在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。
如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。
组成角色 | 具体 | 关系 | 作用 |
---|---|---|---|
抽象命令类(Command) | Command | 声明执行命令的接口,拥有执行命令的抽象方法 | 声明执行命令的接口,拥有执行命令的抽象方法 |
具体命令角色(Concrete Command) | LightOff, LightOn | 抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作 | 抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作 |
实现者/接收者(Receiver) | LightCommandReceiver | 执行命令功能的相关操作,是具体命令对象业务的真正实现者 | 执行命令功能的相关操作,是具体命令对象业务的真正实现者 |
调用者/请求者(Invoker)角色 | RemoteSend | 请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者 | 请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者 |
二. 命令模式实例
二.一 抽象命令 Command
public interface Command {
/**
执行命令
*/
public void execute();
/**
撤销命令
*/
public void undo();
}
二.二 具体命令实现
开灯:
public class LightOn implements Command{
private LightCommandReceiver lightCommandReceiver;
public LightOn( LightCommandReceiver lightCommandReceiver) {
this.lightCommandReceiver = lightCommandReceiver;
}
@Override
public void execute() {
lightCommandReceiver.on();
}
@Override
public void undo() {
lightCommandReceiver.off();
}
}
关灯:
public class LightOff implements Command{
private LightCommandReceiver lightCommandReceiver;
public LightOff(LightCommandReceiver lightCommandReceiver) {
this.lightCommandReceiver = lightCommandReceiver;
}
@Override
public void execute() {
lightCommandReceiver.off();
}
@Override
public void undo() {
lightCommandReceiver.on();
}
}
二.三 接收者 LightCommandReceiver
@Slf4j
public class LightCommandReceiver {
public void on() {
log.info("电灯打开了");
}
public void off() {
log.info("电灯关闭了");
}
}
二.四 请求者 RemoteSend
public class RemoteSend {
private Command command;
public RemoteSend (Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void execute() {
command.execute();
}
public void undo() {
command.undo();
}
}
二.五 测试类使用
@Test
public void oneTest() {
LightCommandReceiver lightCommandReceiver = new LightCommandReceiver();
Command lightOn = new LightOn(lightCommandReceiver);
RemoteSend remoteSend = new RemoteSend(lightOn);
remoteSend.execute();
remoteSend.undo();
Command lightOff = new LightOff(lightCommandReceiver);
remoteSend = new RemoteSend(lightOff);
remoteSend.execute();
remoteSend.undo();
}
本章节的代码放置在 github 上:
https://github.com/yuejianli/DesignPattern/tree/develop/Command
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!