概念:
命令模式将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开,实现二者之间的解耦合。
案例:
Setting 通过命令模式控制手机功能模块(定位,3G网等)的开启与关闭
来看类图:
代码:
先定义Command接口:
public interface Commandable {
public void exe();
}
接下来两个Command接口的实现类:
开启命令和关闭命令,内部持有一个Turnable实例,可构造传入。
public class OpenCommand implements Commandable {
private Turnable turnable;
public OpenCommand(Turnable turnable) {
this.turnable = turnable;
}
@Override
public void exe() {
if (null != turnable) {
turnable.turnon();
}
}
}
public class CloseCommand implements Commandable { private Turnable turnable; public CloseCommand(Turnable turnable) { this.turnable = turnable; } @Override public void exe() { if (null != turnable) { turnable.turnoff(); } } }
接下来Turnable 接口:
public interface Turnable { public void turnon(); public void turnoff(); }
两个Turnable 接口的实现类:
public class GPS implements Turnable { private void close() { System.out.println(String.format("%s.close() called!", this.getClass().getName())); } private void open() { System.out.println(String.format("%s.open() called!", this.getClass().getName())); } @Override public void turnon() { open(); } @Override public void turnoff() { close(); } }
public class G3 implements Turnable {
private void close() {
System.out.println(String.format("%s.close() called!", this.getClass().getName()));
}
private void open() {
System.out.println(String.format("%s.open() called!", this.getClass().getName()));
}
@Override
public void turnon() {
open();
}
@Override
public void turnoff() {
close();
}
}
最后遥控器类:持有一个Commandable 实例,可构造传入,也可动态改变。
public class Setting {
private Commandable command;
public Setting(Commandable command) {
this.command = command;
}
public Setting setCommand(Commandable command) {
this.command = command;
return this;
}
public void action() {
if (null != command) {
command.exe();
}
}
}
测试类:
public class WorkClass {
public void test() {
GPS gps = new GPS();
G3 g3 = new G3();
Setting setting = new Setting(new OpenCommand(gps));
setting.action();
setting.setCommand(new OpenCommand(g3)).action();
setting.setCommand(new CloseCommand(g3)).action();
setting.setCommand(new CloseCommand(gps)).action();
//替换命令
setting.setCommand(new OpenCommand(gps)).setCommand(new OpenCommand(g3)).action();
}
}
测试输出结果:
designpatten.action.GPS.open() called!
designpatten.action.G3.open() called!
designpatten.action.G3.close() called!
designpatten.action.GPS.close() called!
designpatten.action.G3.open() called!
总结:
优点:
降低系统的耦合度
新的命令可以很容易地加入到系统中
也可比较容易地设计组合命令
缺点:
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将限制了命令模式的使用。
适用环境:
系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
系统需要在不同的时间指定请求,将请求排队和执行请求。
系统需要支持命令的撤销和恢复操作。
系统需要将一组操作组合在一起,即支持宏命令。