命令模式的定义是:将“请求”封装称对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持撤销的操作。(参数化是指命令的封装对象中有成员(命令发出者)和执行(即动作方法))。(注:复合命令是指成员或执行的数量大于1)
解决的问题:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
它的类图如下:
可见模式中的角色主要有:
(1)抽象命令(Command)定义命令的接口,声明执行的方法。
(2)具体命令(ConcreteCommand):具体命令,实现要执行的方法,它通常是“虚”的实现;通常会有接收者,并调用接收者的功能来完成命令要执行的操作。
(3)接收者(Receiver):真正执行命令的对象。任何类都可能成为一个接收者,只要能实现命令要求实现的相应功能。
(4)调用者(Invoker):要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
(5)客户端(Client):创建具体的命令对象,命令由客户端来创建,并设置命令的接收者。
简单例子:
使用命令模式实现遥控器,遥控器上的不同按钮控制电灯的开关及亮度、天花板风扇的开关及转速等,支持撤销
1、命令接口:Command
1 public interface Command { 2 public void execute(); 3 }
2、对Receiver(灯)实现开关命令
1 public class LightOnCommand implements Command { 2 Light light; 3 public LightOnCommand(Light light) { 4 this.light = light; 5 } 6 public void execute() { 7 light.on(); 8 } 9 } 10 11 public class LightOffCommand implements Command { 12 Light light; 13 public LightOffCommand(Light light) { 14 this.light = light; 15 } 16 public void execute() { 17 light.off(); 18 } 19 }
3、实现Invoker控制
1 public class SimpleRemoteControl { 2 Command slot; 3 public SimpleRemoteControl() {} 4 public void setCommand(Command command) { 5 slot = command; 6 } 7 public void buttonWasPressed() { 8 slot.execute(); 9 } 10 }
4、Client使用Invoker控制器
1 public class RemoteControlTest { 2 public static void main(String[] args) { 3 SimpleRemoteControl remote = new SimpleRemoteControl(); 4 Light light = new Light(); 5 LightOnCommand lightOn = new LightOnCommand(light); //创建命令 6 remote.setCommand(lightOn); 7 remote.buttonWasPressed(); 8 } 9 }