命令模式:将“请求”封装成对象,以便使用不同的请求,队列或日志来参数化其他对象。命令模式也支持撤销的操作。
通过封装方法调用,我们可以把运算块包装成形。所以调用此运算的对象不需要关心事情是如何进行的,只需要知道如何使用包装成形的方法来完成它就可以了。
一个命令对象(如下文的LightOnCommand)通过在特定的接收者(Light)上绑定一组动作(On())来封装一个请求,要达到这一点,命令对象将动作和接收者包进对象中。这个对象只暴露一个类似Excute()的方法,当此方法被调用时,接收者就会执行这些动作。
接收者存在的必要性(解耦):一般来说,我们尽量设计“傻瓜”命令对象,它只知道调用一个接收者的行为。然而许多“聪明”的命令对象会实现许多逻辑,直接完成一个请求,这样一来,调用者和接收者之间的解耦程度比不上“傻瓜”命令对象。
代码示例:
1.实现命令接口
public interface Command { public void Excute(); }
2.实现一个打开电灯的命令对象
public class LightOnCommand implements Command { // 电灯对象 Light light; public LightOnCommand(Light light) { // 构造器传入某个电灯,以便让这个命令对象控制,然后记录在实例变量中。 // 一旦调用Excute()方法,这个电灯对象就会成为接收者,负责接收请求。 this.light = light; } public void Excute() { // 命令对象调用接收者(light)的方法。 light.On(); } }
3.使用LightOnCommand类
// 简易遥控器 public class SimpleRemoteControl { // 有一个插槽持有命令,这个命令控制着一个装置 Command slot; public SimpleRemoteControl() {} public void SetCommand(Command command) { // 设置插槽控制命令,客户可以调用该方法设置遥控器的行为 slot = command; } public void buttonWasPressed() { // 当按下遥控器按钮,当前命令衔接插槽,并调用Excute()方法 // 从该方法也可以看出,发出请求的对象(SimpleRemoteControl)与接收与执行这些请求的对象(Light)之间的解耦关系 slot.Excute(); } }