命令模式:在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)。
命令模式的本质:对命令进行封装,将发出命令的责任和执行命令的责任分割开。
优点:降低对象之间的耦合度;新的命令可以很容易地加入到系统中;可以比较容易地设计一个组合命令;调用同一方法实现不同的功能。
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
类图:
下面看个例子:
命令接口:
public interface Command {
void execute();//执行操作
void unDo();//撤销操作
}
行为实现类:
public class Light {
public void on() {
Log.e("zhang", "打开灯");
}
public void off() {
Log.e("zhang", "关闭灯");
}
}
public class FengShan {//风扇
public enum State{
H,//高档
M,//中档
L,//低档
S//0档--停止
}
public void change(State state) {
switch (state) {
case H:
start(State.H);
break;
case M:
start(State.M);
break;
case L:
start(State.L);
break;
case S:
stop();
break;
default:
stop();
break;
}
}
public void stop() {
Log.e("zhang", "关闭");
}
public void start(State state) {
switch (state) {
case H:
Log.e("zhang", "高档");
break;
case M:
Log.e("zhang", "中档");
break;
case L:
Log.e("zhang", "低档");
break;
}
}
}
行为的请求者:具体的命令类:
开灯命令:
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
if (light != null) {
light.on();
}
}
@Override
public void unDo() {
if (light!=null){
light.off();
}
}
}
关灯命令
public class LightOffCommand implements Command{
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
if (light != null) {
light.off();
}
}
@Override
public void unDo() {
if (light!=null){
light.on();
}
}
}
风扇命令类:
public class FengShanCommand implements Command {
private FengShan fengShan;
private FengShan.State state = FengShan.State.S;
private FengShan.State lastState;
public FengShanCommand(FengShan fengShan) {
this.fengShan = fengShan;
}
public void setState(FengShan.State state) {
//记录上次执行的状态
lastState = this.state;
this.state = state;
}
@Override
public void execute() {
if (fengShan != null && state != null && state != lastState) {
fengShan.change(state);
}
}
@Override
public void unDo() {
if (fengShan != null && state != lastState) {
fengShan.change(lastState);
}
}
}
程序入口:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Light light = new Light();
FengShan fengShan = new FengShan();
Command commandOn = new LightOnCommand(light);
Control controlOn = new Control(commandOn);
controlOn.execute();
Command commandOff = new LightOffCommand(light);
Control controlOff = new Control(commandOff);
controlOff.execute();
controlOn.unDo();//撤销打开灯的命令
FengShanCommand commandF = new FengShanCommand(fengShan);
commandF.setState(FengShan.State.H);
Control controlF = new Control(commandF);
controlF.execute();
commandF.setState(FengShan.State.M);
commandF.execute();
//撤销风扇的上一次操作
controlF.unDo();
//通过集合组装起来
List<Command> commands = new ArrayList<>();
commands.add(commandOn);
commands.add(commandOff);
commands.add(commandF);
Control control = new Control(commands);
control.executeAll();
control.unDoAll();
}
}