概念理解
一个命令有命令的发出者和执行者,命令模式的主要目的是将这两者主体解耦。简单理解,发出的命令(不管是什么)是一个对象,对象中仅有做和不做两个方法。命令如何执行,有具体的命令实现对象调用命令接收者来具体执行。
需求描述
遥控器需要控制家中电灯的开关,以及冰箱的开关和设置温度。
设计一:直接方式
从直接实现的结构可以看出,发出命令者和执行命令者存在着紧耦合,这种结构不利于扩展。
public class Fridge {
private int temperature=10;
public void on() {
System.out.println("fridge is on ");
}
public void off() {
System.out.println("fridge is off");
}
public void temperatureUp() {
this.temperature++;
System.out.println(" up temperature:" + temperature + " is set");
}
public void temperatureDown() {
this.temperature--;
System.out.println(" down temperature:" + temperature + " is set");
}
}
public class Light {
public Light() {
}
public void on() {
System.out.println("light is on ");
}
public void off() {
System.out.println("light is off");
}
}
public class Controller {
private Light light = new Light();
private Fridge fridge = new Fridge();
public void invoke(int slot) {
switch (slot) {
case 1:
light.on();
case 2:
light.off();
case 3:
fridge.on();
case 4:
fridge.off();
case 5:
fridge.temperatureUp();
case 6:
fridge.temperatureDown();
default:
break;
}
}
}
命令模式的主要目的是加入中间层,命令对象,将命令发出者和执行者解耦。
设计二:命令模式
命令模式实际上就是在命令发出者和接受者之间加入了中间层——命令对象。
挑选几个代码实例
public interface Commander {
void execute();
void undo();
}
public class LightOnCommander implements Commander {
private Light light;
public LightOnCommander() {
this.light = new Light();
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
public class LightOffCommander implements Commander{
private Light light;
public LightOffCommander(){
this.light = new Light();
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
public class ControlPannel {
private int slot;
private Commander[] onCommanders;
private Commander[] offCommanders = new Commander[5];
private Deque<Commander> stack;
public ControlPannel() {
onCommanders = new Commander[5];
offCommanders = new Commander[5];
Commander noCommander = new NoCommander();
for (int i = 0; i < 5; i++) {
onCommanders[i] = noCommander;
offCommanders[i] = noCommander;
}
stack = new ArrayDeque<Commander>();
}
public void setCommanders(Commander onCommande, Commander offCommander, int slot) {
onCommanders[slot] = onCommande;
offCommanders[slot] = offCommander;
}
public void onButton(int slot) {
onCommanders[slot].execute();
stack.push(onCommanders[slot]);
}
public void offButton(int slot) {
offCommanders[slot].execute();
stack.push(offCommanders[slot]);
}
public void undoCommander() {
stack.pop().undo();
}
}
public class TestApp {
public static void main(String[] args) {
ControlPannel panel = initPanel();
panel.onButton(1);
panel.onButton(2);
panel.undoCommander();
panel.undoCommander();
}
public static ControlPannel initPanel() {
ControlPannel pannel = new ControlPannel();
pannel.setCommanders(new LightOnCommander(), new LightOffCommander(), 0);
pannel.setCommanders(new FridgeOnCommander(), new FridgeOffCommander(), 1);
pannel.setCommanders(new FridgeTmeperatureOnCommander(), new FrigdeTemperatureDownCommander(), 2);
return pannel;
}
}
注意点
优点:命令模式的主要目的是解耦,层次分明,各司其职,方便扩展
缺点:命令模式因为其层次结构的存在,如果存在多个命令,则会造成命令类过于庞大。
具体代码实例参见https://github.com/jxl198/designPattern/tree/master/commander
网友评论