一、命令模式介绍
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
命令模式使得请求发送者与接收者消除彼此之间的耦合,让对象关系更加灵活。
命令模式角色:
Receiver
真正的命令执行对象。Command
所有命令。Invoker
使用命令对象的入口。此处我们有一个诉求:
- 长官通过调用进攻和撤退命令,下达给士兵去执行,而士兵不用关心给我们下命令的长官是谁,只负责去执行。
- 解决方案:采用命令模式。
二、命令模式使用
2.1 示例关系:
2.2 代码实现:
- 命令
/* *
* 1. 命令接口。
*/
interface ICommand {
void execute();
}
/* *
* 2. 进攻命令类实现命令接口。
*/
class AttackCommand implements ICommand {
/* *
* 持有命令接收者(即命令执行者)。
*/
private Soldier soldier;
public AttackCommand(Soldier soldier) {
this.soldier = soldier;
}
@Override
public void execute() {
soldier.ready();
}
}
/* *
* 3. 撤退命令类实现命令接口。
*/
class RetreatCommand implements ICommand {
/* *
* 持有命令接收者(即命令执行者)。
*/
private Soldier soldier;
public RetreatCommand(Soldier soldier) {
this.soldier = soldier;
}
@Override
public void execute() {
soldier.run();
}
}
/* *
* 4. 无命令类实现命令接口。
*/
class NoCommand implements ICommand {
/* *
* 空实现(缺省)。
*/
@Override
public void execute() {
}
}
- 命令接收者与调用者
/* *
* 5. 士兵类-命令接收者(Receiver)。
*/
class Soldier {
public void ready() {
System.out.println(" 士兵就绪,发起进攻~ ");
}
public void run() {
System.out.println(" 局势不对,立马撤退! ");
}
}
/* *
* 6. 长官类-命令调用者(Invoker)
*/
class Ephor {
/* *
* 持有ICommand命令。
*/
private ICommand iCommand;
public Ephor() {
}
/* *
* 设置进攻和撤退命令,完成调用。
*/
public void setCommand(ICommand attackCommand, ICommand retreatCommand) {
for (int i = 1; i < 3; i++) {
System.out.println(" 长官第" + i + "次下达进攻命令: ");
attackCommand.execute();
System.out.println();
}
System.out.println(" 长官命令变更: ");
retreatCommand.execute();
}
}
- 客户端调用
/* *
* 7. 客户端调用。
*/
public class Client {
public static void main(String[] args) {
// 创建命令接收者。
Soldier soldier = new Soldier();
// 创建命令。
AttackCommand attackCommand = new AttackCommand(soldier);
RetreatCommand retreatCommand = new RetreatCommand(soldier);
// 调用者发起调用。
new Ephor().setCommand(attackCommand, retreatCommand);
// 长官第1次下达进攻命令:
// 士兵就绪,发起进攻~
//
// 长官第2次下达进攻命令:
// 士兵就绪,发起进攻~
//
// 长官命令变更:
// 局势不对,立马撤退!
}
}
三、命令模式总结
优点:
- 调用者与接收者之间,通过命令进行了解耦。
- 容易实现对请求的撤销和重做。
- 空命令也是很关键的一种方式,省去了判空的操作。
缺点:
- 可能导致某些系统有过多的具体命令类,增加系统复杂度。
应用场景:
Spring
框架中JdbcTemplate
源码。- 界面按钮。
- 订单的撤销/恢复、触发-反馈机制。
四 、结束语
“-------怕什么真理无穷,进一寸有一寸的欢喜。”
微信公众号搜索:饺子泡牛奶。