第七篇 调整类间关系 第二十一章 - 命令模式
如果说责任链模式关注的是“水平方向”的上下游类间关系,那么命令模式关注的是“垂直方向”的上下级类间关系。
这里的上下级类间关系是指某功能(或方法)的请求类与执行类之间的调用关系。
看个例子。
// 设备驱动程序
public class Driver {
public static void work() {}
}
// 打印服务
public class Printer {
// 打印
public void print() {
// 设备驱动程序执行任务
Driver.work();
}
}
上例中Printer为打印功能的请求类(上级),Driver则为执行类(下级),它们构成了上下级关系。
看得出来,这是一种紧密的耦合关系,请求类与执行类直接绑定在一起了。如果有扩展需求,我们可以尝试将两者“解耦”。
来看看命令模式提供的解耦思路。
// 命令接受者
public interface Receiver {
public void work();
}
// 打印命令接受者
public class PrintReceiver implements Receiver {
@Override
public void work() {
Driver.work();
}
}
// 命令
public abstract class Command {
public Receiver receiver;
// 命令与命令接受者之间的“桥梁”
public Command(Receiver obj) {
this.receiver = obj;
}
// 执行命令
public abstract void execute();
}
// 打印命令
public class PrintCommand extends Command {
public PrintCommand(Receiver obj) {
super(obj);
}
// 执行打印命令
@Override
public void execute() {
super.receiver.work();
}
}
// 测试类
public class Test {
public void test() {
// 命令接受者
Receiver r = new PrintReceiver();
// 命令
Command c = new PrintCommand(r);
c.execute();
}
}
这里设立了“命令”与“命令接受者”两种角色,将直接的功能调用拆分成了需求方“下达命令”与命令接受者“执行命令”两个步骤。
命令与命令接受者的关联关系建立在桥接模式的基础上,为双方预留了扩展空间。
这种松散的耦合关系使得我们有机会“拦截”功能调用并植入额外的操作(如维护打印队列)。
如下所示。
// 打印命令
public class PrintCommand extends Command {
public PrintCommand(Receiver obj) {
super(obj);
}
// 执行打印命令
@Override
public void execute() {
this.doSomething();// 植入额外的操作
super.receiver.work();
}
private void doSomething() {}
}
必要时可以引入“通信员”角色,由它专门处理繁重的“拦截命令”工作。
如下所示。
// 通信员
public class Messenger {
private Command command;
public void setCommand(Command obj) {
this.command = obj;
}
public void execute() {
this.doSomething();// 植入额外的操作
this.command.execute();
}
private void doSomething() {}
}
// 测试类
public class Test {
public void test() {
// 命令接受者
Receiver r = new PrintReceiver();
// 命令
Command c = new PrintCommand(r);
// 通信员传达命令
Messenger obj = new Messenger();
obj.setCommand(c);
obj.execute();
}
}
浙公网安备 33010602011771号