合工大很牛很牛牛

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            14 Posts :: 1 Stories :: 37 Comments :: 0 Trackbacks

          Command Pattern的目的在于分離命令的發出者和命令的執行者。就好比在飯店吃飯,作為客戶(命令的發出者),你無需直接跟廚師說明要點什么菜,只要把菜單給服務員就行了,而服務員并不負責燒菜,只要把菜單交給廚師(執行者)即可,廚師會根據菜單做菜了。這兩者被分離了。

           

          下面來實現這個點菜的過程:我們要點兩個菜,burgermalt。最簡單的實現如下:

          package javaapplication29;

           

          public class Main {

              public static void main(String[] args) {

                  Cook cook = new Cook();

                  cook.burger();

                  cook.malt();

              }

          }

           

          class Cook {

              void burger() {

                  System.out.println("burger maked");

              }

              void malt() {

                  System.out.println("malt maked");

              }

          }

           

          這里有個問題:我們要點什么菜,是寫在主函數里的。如果要點的菜有所改變,比如第二個人要點菜,點其他菜,那么主函數里的代碼就要重寫。這里就出現了所謂的“變化沒有被封裝”的問題。這里的代碼實現過程就好比顧客直接跟廚師說要吃什么菜一樣。

           

          這里我們引入“菜單”,所謂菜單的作用在于:把變化的“點什么菜”封裝到菜單這個對象里面去。實際上就是把主函數中變化的部分封裝到一個類中去了。

          package javaapplication29;

           

          public class Main {

              public static void main(String[] args) {

                  Cook cook = new Cook();

                  Manu1 manu1 = new Manu1(cook);

                  manu1.orderup();

              }

          }

           

          class Cook {

              void burger() {

                  System.out.println("burger maked");

              }

              void malt() {

                  System.out.println("malt maked");

              }

          }

           

          class Manu1 {

              Cook cook;

              public Manu1(Cook cook) {

                  this.cook = cook;

              }

              public void orderup() {

                  cook.burger();

                  cook.malt();

              }

          }

           

           

          如果有第二個菜單,我們就再寫第二個類Manu2出來:

          package javaapplication29;

           

          public class Main {

              public static void main(String[] args) {

                  Cook cook = new Cook();

                  Manu1 manu1 = new Manu1(cook);

                  manu1.orderup();

                 

                  Manu2 manu2=new Manu2(cook);

                  manu2.orderup();

              }

          }

           

          class Cook {

              void burger() {

                  System.out.println("burger maked");

              }

              void malt() {

                  System.out.println("malt maked");

              }

          }

           

          class Manu1 {

              Cook cook;

              public Manu1(Cook cook) {

                  this.cook = cook;

              }

              public void orderup() {

                  cook.burger();

                  cook.malt();

              }

          }

           

          class Manu2 {

              Cook cook;

              public Manu2(Cook cook) {

                  this.cook = cook;

              }

              public void orderup() {

                  cook.burger();

              }

          }

                    

          這里我們發現Manu1Manu2兩個類形式幾乎相通,只是orderup()函數內執行的東西不一樣。在主函數中,要執行第二個菜單還得重新生成一個對象,Manu2 manu2=new Manu2(cook);  而不能直接切換,manu1=new Manu2(cook);   這很不爽,由此很容易想到用一個父類,讓Manu1Manu2繼承之,如下:

           

          package javaapplication29;

           

          public class Main {

              public static void main(String[] args) {

                  Cook cook = new Cook();

                  Manu manu = new Manu1(cook);

                  manu.orderup();

           

                  manu = new Manu2(cook);

                  manu.orderup();

              }

          }

           

          class Cook {

              void burger() {

                  System.out.println("burger maked");

              }

              void malt() {

                  System.out.println("malt maked");

              }

          }

           

          abstract class Manu {

              abstract public void orderup();

          }

           

          class Manu1 extends Manu {

              Cook cook;

              public Manu1(Cook cook) {

                  this.cook = cook;

              }

              public void orderup() {

                  cook.burger();

                  cook.malt();

              }

          }

           

          class Manu2 extends Manu {

              Cook cook;

              public Manu2(Cook cook) {

                  this.cook = cook;

              }

              public void orderup() {

                  cook.burger();

              }

          }

           

          這個實際上變成工廠模式了。我們看到主函數中:

          Manu manu = new Manu1(cook);

          manu.orderup();

          這里,命令的發出是通過菜單的orderup方法發出的。可實際中,菜單是不能發命令的,而是客戶通過服務員發命令的。我們需要一個Waitress這個對象來裝載各種菜單,并對廚師發出點菜的命令(通過調用Manuorderup方法)。如下:

           

          package javaapplication29;

           

          public class Main {

              public static void main(String[] args) {

                  Cook cook = new Cook();

                  Waitress waitress = new Waitress();

           

                  Manu manu = new Manu1(cook);

                  waitress.setManu(manu);

                  waitress.callCook();

           

                  manu = new Manu2(cook);

                  waitress.setManu(manu);

                  waitress.callCook();

              }

          }

           

          class Cook {

              void burger() {

                  System.out.println("burger maked");

              }

              void malt() {

                  System.out.println("malt maked");

              }

          }

           

          abstract class Manu {

              abstract public void orderup();

          }

           

          class Manu1 extends Manu {

              Cook cook;

              public Manu1(Cook cook) {

                  this.cook = cook;

              }

              public void orderup() {

                  cook.burger();

                  cook.malt();

              }

          }

           

          class Manu2 extends Manu {

              Cook cook;

              public Manu2(Cook cook) {

                  this.cook = cook;

              }

              public void orderup() {

                  cook.burger();

              }

          }

           

          class Waitress {

              Manu manu;

              public void setManu(Manu manu) {

                  this.manu = manu;

              }

              public void callCook() {

                  manu.orderup();

              }

          }

          在這個程序里,我們發現其實Waitress在主程序中只知道要callCook()

          waitress.callCook();

          而她并不知道callCook()在具體執行什么,因為Waitress類中的manu是一個抽象類的對象,而callCook()方法中的manu.orderup() 是抽象方法,鬼知道它的具體實現是什么。

           

          這就是Command Pattern的目的:把命令封裝成對象(Manu1Manu2),讓調用命令的人(Waitress)裝載該對象(setManu),隨時可以發出該命令(callCook)。而調用命令的人,并不知道該命令的具體執行過程。

           

          這有點類似于給工廠模式中的抽象工廠添加了一個裝載器。值得注意的是,在工廠模式中,頂層的抽象工廠一般是抽象類,而在命令模式中,頂層的一般都是接口。其實到底用抽象類還是接口并不重要!因為在某種程度上,他們都是Interface。到底用哪個,根據需要使用,畢竟可以實現多接口而不能繼承多個抽象類。Command Pattern的關鍵不在于這里,而在于裝載器和工廠模式的結合。

           

          head first design pattern》上要實現一個遠程控制器,思路跟上面一樣。代碼如下所示:

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  Command command = new LightOnCommand(light);

                  RemoteControl rc = new RemoteControl();

                  rc.setControl(command);

                  rc.ButtonDown();

           

                  GarageDoor garageDoor = new GarageDoor();

                  command = new GarageDoorOpenCommand(garageDoor);

                  rc.setControl(command);

                  rc.ButtonDown();

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

          }

           

          interface Command {

              public void execute();

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

          }

           

          class RemoteControl {

              Command command;

              public void setControl(Command command) {

                  this.command = command;

              }

              public void ButtonDown() {

                  command.execute();

              }

          }

           

           

          以上設計出的遠程控制器只有一個slot,對應一個按鈕。現在如果要實現7slot,每個slot對應一個“打開”按鈕,則需要把RemoteControl這個類改動一下:

           

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  GarageDoor garageDoor = new GarageDoor();

                  RemoteControl rc = new RemoteControl();

           

                  Command command = new LightOnCommand(light);

                  rc.setControl(0, command);

           

                  command = new GarageDoorOpenCommand(garageDoor);

                  rc.setControl(1, command);

           

                  rc.buttonDown(0);

                  rc.buttonDown(1);

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

          }

           

          interface Command {

              public void execute();

          }

           

          class noCommand implements Command {

              public void execute() {

                  System.out.println("no command here.");

              }

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

          }

           

          class RemoteControl {

              Command[] onCommands;

          Command noCommand = new noCommand();

           

              public RemoteControl() {

                  onCommands = new Command[7];

                  for (int i = 0; i < 7; i++) {

                      onCommands[i] = noCommand; //初始化7個槽對應的按鈕指令為空

                  }

              }

              public void setControl(int slot, Command command) {

                  onCommands[slot] = command;

              }

              public void buttonDown(int slot) {

                  onCommands[slot].execute();

              }

          }

           

          對比之前的只有一個slot的程序,RemoteControl類添加了一個初始化作用的構造函數,并在每個方法的參數表里添加了slot參數。

           

          如果想要有7slot,每個slot都對應“開”、“關”兩個按鈕,則同理,講RemoteControl中的參數再各增加一個即可,如下:

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  GarageDoor garageDoor = new GarageDoor();

                  RemoteControl rc = new RemoteControl();

           

                  Command onCommand = new LightOnCommand(light);

                  Command offCommand = new LightOffCommand(light);

                  rc.setControl(0, onCommand, offCommand);

           

                  onCommand = new GarageDoorOpenCommand(garageDoor);

                  offCommand = new GarageDoorCloseCommand(garageDoor);

                  rc.setControl(1, onCommand, offCommand);

           

                  rc.onButtonDown(0);

                  rc.offButtonDown(1);

                  rc.offButtonDown(0);

                  rc.onButtonDown(1);

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

              void off() {

                  System.out.println("turn light off");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

              public void close() {

                  System.out.println("close GarageDoor");

              }

          }

           

          interface Command {

              public void execute();

          }

           

          class noCommand implements Command {

              public void execute() {

                  System.out.println("no command here.");

              }

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

          }

           

          class LightOffCommand implements Command {

              Light light;

              LightOffCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.off();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

          }

           

          class GarageDoorCloseCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorCloseCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.close();

              }

          }

           

          class RemoteControl {

              Command[] onCommands;

          Command[] offCommands;

          Command noCommand = new noCommand();

           

              public RemoteControl() {

                  onCommands = new Command[7];

                  offCommands = new Command[7];

                  for (int i = 0; i < 7; i++) {

                      onCommands[i] = noCommand;

                      offCommands[i] = noCommand;

                  }

              }

              public void setControl(int slot, Command onCommand, Command offCommand) {

                  onCommands[slot] = onCommand;

                  offCommands[slot] = offCommand;

              }

              public void onButtonDown(int slot) {

                  onCommands[slot].execute();

              }

              public void offButtonDown(int slot) {

                  offCommands[slot].execute();

              }

          }

           

           

          如何給上面的程序添加一個undo按鈕呢,就是撤銷上一次的操作。

          (1)       我們要給Command接口以及它的所有實現體(LightOnCommand, GarageCloseCommand等)添加undo()方法,undo執行的內容就是和execute()執行相反的即可。

          (2)       我們還在RemoteControl類中,想辦法記錄最后一次執行的是哪個XXXCommand

           

          實現如下:

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  GarageDoor garageDoor = new GarageDoor();

                  RemoteControl rc = new RemoteControl();

           

                  Command onCommand = new LightOnCommand(light);

                  Command offCommand = new LightOffCommand(light);

                  rc.setControl(0, onCommand, offCommand);

           

                  onCommand = new GarageDoorOpenCommand(garageDoor);

                  offCommand = new GarageDoorCloseCommand(garageDoor);

                  rc.setControl(1, onCommand, offCommand);

           

                  rc.onButtonDown(0);

                  rc.undoButtonDown();

                  rc.offButtonDown(1);

                  rc.offButtonDown(0);

                  rc.onButtonDown(1);

                  rc.undoButtonDown();

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

              void off() {

                  System.out.println("turn light off");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

              public void close() {

                  System.out.println("close GarageDoor");

              }

          }

           

          interface Command {

              public void execute();

              public void undo();

          }

           

          class noCommand implements Command {

              public void execute() {

                  System.out.println("no command here.");

              }

              public void undo() {

                  System.out.println("no command here.");

              }

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

              public void undo() {

                  light.off();

              }

          }

           

          class LightOffCommand implements Command {

              Light light;

              LightOffCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.off();

              }

              public void undo() {

                  light.on();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

              public void undo() {

                  garageDoor.close();

              }

          }

           

          class GarageDoorCloseCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorCloseCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.close();

              }

              public void undo() {

                  garageDoor.open();

              }

          }

           

          class RemoteControl {

              Command[] onCommands;

              Command[] offCommands;

              Command noCommand = new noCommand();

              Command lastCommand;

              public RemoteControl() {

                  onCommands = new Command[7];

                  offCommands = new Command[7];

                  for (int i = 0; i < 7; i++) {

                      onCommands[i] = noCommand;

                      offCommands[i] = noCommand;

                  }

              }

              public void setControl(int slot, Command onCommand, Command offCommand) {

                  onCommands[slot] = onCommand;

                  offCommands[slot] = offCommand;

              }

              public void onButtonDown(int slot) {

                  onCommands[slot].execute();

                  lastCommand = onCommands[slot];

              }

              public void offButtonDown(int slot) {

                  offCommands[slot].execute();

                  lastCommand = offCommands[slot];

              }

              public void undoButtonDown() {

                  lastCommand.undo();

              }

          }

           

          電器的功能可能不止“開”和“關”,比如電風扇,有換擋功能。對于電風扇的HighMediumLow三個檔位,每個要寫一個單獨的FanXXXCommand類。對每個檔位做undo的時候,不能直接簡單的取反,要找到上一次的檔位才行。

           

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  GarageDoor garageDoor = new GarageDoor();

                  RemoteControl rc = new RemoteControl();

           

                  Command onCommand = new LightOnCommand(light);

                  Command offCommand = new LightOffCommand(light);

                  rc.setControl(0, onCommand, offCommand);

           

                  onCommand = new GarageDoorOpenCommand(garageDoor);

                  offCommand = new GarageDoorCloseCommand(garageDoor);

                  rc.setControl(1, onCommand, offCommand);

           

                  rc.onButtonDown(0);

                  rc.undoButtonDown();

                  rc.offButtonDown(1);

                  rc.offButtonDown(0);

                  rc.onButtonDown(1);

                  rc.undoButtonDown();

           

                  Fan fan = new Fan();

                  onCommand = new FanHighCommand(fan);

                  offCommand = new FanOffCommand(fan);

                  rc.setControl(2, onCommand, offCommand);

                  rc.onButtonDown(2);

                  rc.offButtonDown(2);

                  rc.undoButtonDown();

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

              void off() {

                  System.out.println("turn light off");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

              public void close() {

                  System.out.println("close GarageDoor");

              }

          }

           

          class Fan {

              public final int HIGH = 3;

              public final int MEDIUM = 2;

              public final int LOW = 1;

              public final int OFF = 0;

              public int speed = 0;

              public void high() {

                  speed = HIGH;

                  System.out.println("Fan's speed is " + speed);

              }

              public void low() {

                  speed = LOW;

                  System.out.println("Fan's speed is " + speed);

              }

              public void medium() {

                  speed = MEDIUM;

                  System.out.println("Fan's speed is " + speed);

              }

              public void off() {

                  speed = OFF;

                  System.out.println("Fan's speed is " + speed);

              }

              public int getSpeed() {

                  return speed;

              }

          }

           

          interface Command {

              public void execute();

              public void undo();

          }

           

          class noCommand implements Command {

              public void execute() {

                  System.out.println("no command here.");

              }

              public void undo() {

                  System.out.println("no command here.");

              }

          }

           

          class FanHighCommand implements Command {

              Fan fan;

              int preSpeed;

              FanHighCommand(Fan fan) {

                  this.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.high();

              }

              public void undo() {

                  if (preSpeed == fan.HIGH) {

                      fan.high();

                  }

                  else if (preSpeed == fan.MEDIUM) {

                      fan.medium();

                  }

                  else if (preSpeed == fan.LOW) {

                      fan.low();

                  }

                  else if (preSpeed == fan.OFF) {

                      fan.off();

                  }

              }

          }

           

          class FanOffCommand implements Command {

              Fan fan;

              int preSpeed;

              FanOffCommand(Fan fan) {

                  this.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.off();

              }

              public void undo() {

                  if (preSpeed == fan.HIGH) {

                      fan.high();

                  }

                  else if (preSpeed == fan.MEDIUM) {

                      fan.medium();

                  }

                  else if (preSpeed == fan.LOW) {

                      fan.low();

                  }

                  else if (preSpeed == fan.OFF) {

                      fan.off();

                  }

              }

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

              public void undo() {

                  light.off();

              }

          }

           

          class LightOffCommand implements Command {

              Light light;

              LightOffCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.off();

              }

              public void undo() {

                  light.on();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

              public void undo() {

                  garageDoor.close();

              }

          }

           

          class GarageDoorCloseCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorCloseCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.close();

              }

              public void undo() {

                  garageDoor.open();

              }

          }

           

          class RemoteControl {

              Command[] onCommands;

              Command[] offCommands;

              Command noCommand = new noCommand();

              Command lastCommand;

              public RemoteControl() {

                  onCommands = new Command[7];

                  offCommands = new Command[7];

                  for (int i = 0; i < 7; i++) {

                      onCommands[i] = noCommand;

                      offCommands[i] = noCommand;

                  }

              }

              public void setControl(int slot, Command onCommand, Command offCommand) {

                  onCommands[slot] = onCommand;

                  offCommands[slot] = offCommand;

              }

              public void onButtonDown(int slot) {

                  onCommands[slot].execute();

                  lastCommand = onCommands[slot];

              }

              public void offButtonDown(int slot) {

                  offCommands[slot].execute();

                  lastCommand = offCommands[slot];

              }

              public void undoButtonDown() {

                  lastCommand.undo();

              }

          }

           

          我們看到FanHighCommandFanOffCommand中有重復的undo,很容易想到,把它們給“抽象工廠”了:

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  GarageDoor garageDoor = new GarageDoor();

                  RemoteControl rc = new RemoteControl();

           

                  Command onCommand = new LightOnCommand(light);

                  Command offCommand = new LightOffCommand(light);

                  rc.setControl(0, onCommand, offCommand);

           

                  onCommand = new GarageDoorOpenCommand(garageDoor);

                  offCommand = new GarageDoorCloseCommand(garageDoor);

                  rc.setControl(1, onCommand, offCommand);

           

                  rc.onButtonDown(0);

                  rc.undoButtonDown();

                  rc.offButtonDown(1);

                  rc.offButtonDown(0);

                  rc.onButtonDown(1);

                  rc.undoButtonDown();

           

                  Fan fan = new Fan();

                  onCommand = new FanHighCommand(fan);

                  offCommand = new FanOffCommand(fan);

                  rc.setControl(2, onCommand, offCommand);

                  rc.onButtonDown(2);

                  rc.offButtonDown(2);

                  rc.undoButtonDown();

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

              void off() {

                  System.out.println("turn light off");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

              public void close() {

                  System.out.println("close GarageDoor");

              }

          }

           

          class Fan {

              public final int HIGH = 3;

              public final int MEDIUM = 2;

              public final int LOW = 1;

              public final int OFF = 0;

              public int speed = 0;

              public void high() {

                  speed = HIGH;

                  System.out.println("Fan's speed is " + speed);

              }

              public void low() {

                  speed = LOW;

                  System.out.println("Fan's speed is " + speed);

              }

              public void medium() {

                  speed = MEDIUM;

                  System.out.println("Fan's speed is " + speed);

              }

              public void off() {

                  speed = OFF;

                  System.out.println("Fan's speed is " + speed);

              }

              public int getSpeed() {

                  return speed;

              }

          }

           

          interface Command {

              public void execute();

              public void undo();

          }

           

          class noCommand implements Command {

              public void execute() {

                  System.out.println("no command here.");

              }

              public void undo() {

                  System.out.println("no command here.");

              }

          }

           

          abstract class FanCommand {

              Fan fan;

              int preSpeed;

              abstract void execute();

              public void undo() {

                  if (preSpeed == fan.HIGH) {

                      fan.high();

                  }

                  else if (preSpeed == fan.MEDIUM) {

                      fan.medium();

                  }

                  else if (preSpeed == fan.LOW) {

                      fan.low();

                  }

                  else if (preSpeed == fan.OFF) {

                      fan.off();

                  }

              }

          }

           

          class FanHighCommand extends FanCommand implements Command {

              FanHighCommand(Fan fan) {

                  super.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.high();

              }

          }

           

          class FanOffCommand extends FanCommand implements Command {

              FanOffCommand(Fan fan) {

                  super.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.off();

              }

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

              public void undo() {

                  light.off();

              }

          }

           

          class LightOffCommand implements Command {

              Light light;

              LightOffCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.off();

              }

              public void undo() {

                  light.on();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

              public void undo() {

                  garageDoor.close();

              }

          }

           

          class GarageDoorCloseCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorCloseCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.close();

              }

              public void undo() {

                  garageDoor.open();

              }

          }

           

          class RemoteControl {

              Command[] onCommands;

              Command[] offCommands;

              Command noCommand = new noCommand();

              Command lastCommand;

              public RemoteControl() {

                  onCommands = new Command[7];

                  offCommands = new Command[7];

                  for (int i = 0; i < 7; i++) {

                      onCommands[i] = noCommand;

                      offCommands[i] = noCommand;

                  }

              }

              public void setControl(int slot, Command onCommand, Command offCommand) {

                  onCommands[slot] = onCommand;

                  offCommands[slot] = offCommand;

              }

              public void onButtonDown(int slot) {

                  onCommands[slot].execute();

                  lastCommand = onCommands[slot];

              }

              public void offButtonDown(int slot) {

                  offCommands[slot].execute();

                  lastCommand = offCommands[slot];

              }

              public void undoButtonDown() {

                  lastCommand.undo();

              }

          }

           

           

          下面我們想讓一個按鈕實現一串命令:關燈,關電扇,開車庫。很顯然,用一個新的XXXCommand實現即可。

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  GarageDoor garageDoor = new GarageDoor();

                  RemoteControl rc = new RemoteControl();

           

                  Command onCommand = new LightOnCommand(light);

                  Command offCommand = new LightOffCommand(light);

                  rc.setControl(0, onCommand, offCommand);

           

                  onCommand = new GarageDoorOpenCommand(garageDoor);

                  offCommand = new GarageDoorCloseCommand(garageDoor);

                  rc.setControl(1, onCommand, offCommand);

           

                  rc.onButtonDown(0);

                  rc.undoButtonDown();

                  rc.offButtonDown(1);

                  rc.offButtonDown(0);

                  rc.onButtonDown(1);

                  rc.undoButtonDown();

           

                  Fan fan = new Fan();

                  onCommand = new FanHighCommand(fan);

                  offCommand = new FanOffCommand(fan);

                  rc.setControl(2, onCommand, offCommand);

                  rc.onButtonDown(2);

                  rc.offButtonDown(2);

                  rc.undoButtonDown();

           

                  onCommand = new ConsecutiveCommands(light, garageDoor, fan);

                  rc.setControl(3, onCommand, null);

                  rc.onButtonDown(3);

                  rc.undoButtonDown();

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

              void off() {

                  System.out.println("turn light off");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

              public void close() {

                  System.out.println("close GarageDoor");

              }

          }

           

          class Fan {

              public final int HIGH = 3;

              public final int MEDIUM = 2;

              public final int LOW = 1;

              public final int OFF = 0;

              public int speed = 0;

              public void high() {

                  speed = HIGH;

                  System.out.println("Fan's speed is " + speed);

              }

              public void low() {

                  speed = LOW;

                  System.out.println("Fan's speed is " + speed);

              }

              public void medium() {

                  speed = MEDIUM;

                  System.out.println("Fan's speed is " + speed);

              }

              public void off() {

                  speed = OFF;

                  System.out.println("Fan's speed is " + speed);

              }

              public int getSpeed() {

                  return speed;

              }

          }

           

          interface Command {

              public void execute();

              public void undo();

          }

           

          class noCommand implements Command {

              public void execute() {

                  System.out.println("no command here.");

              }

              public void undo() {

                  System.out.println("no command here.");

              }

          }

           

          abstract class FanCommand {

              Fan fan;

              int preSpeed;

              abstract void execute();

              public void undo() {

                  if (preSpeed == fan.HIGH) {

                      fan.high();

                  }

                  else if (preSpeed == fan.MEDIUM) {

                      fan.medium();

                  }

                  else if (preSpeed == fan.LOW) {

                      fan.low();

                  }

                  else if (preSpeed == fan.OFF) {

                      fan.off();

                  }

              }

          }

           

          class FanHighCommand extends FanCommand implements Command {

              FanHighCommand(Fan fan) {

                  super.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.high();

              }

          }

           

          class FanOffCommand extends FanCommand implements Command {

              FanOffCommand(Fan fan) {

                  super.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.off();

              }

          }

           

          class ConsecutiveCommands implements Command {

              Light light;

              Fan fan;

              GarageDoor garageDoor;

              int preSpeed;

              ConsecutiveCommands(Light light, GarageDoor garageDoor, Fan fan) {

                  this.light = light;

                  this.garageDoor = garageDoor;

                  this.fan = fan;

              }

              public void execute() {

                  light.off(); //關燈

                  preSpeed = fan.getSpeed(); //記錄原先的電扇檔位

                  fan.off(); //關電扇

                  garageDoor.open() ; //開車庫

              }

              public void undo() {

                  light.on();

                 

          if (preSpeed == fan.HIGH) {

                      fan.high();

                  }

                  else if (preSpeed == fan.MEDIUM) {

                      fan.medium();

                  }

                  else if (preSpeed == fan.LOW) {

                      fan.low();

                  }

                  else if (preSpeed == fan.OFF) {

                      fan.off();

                  }

                

           garageDoor.close();

              }

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

              public void undo() {

                  light.off();

              }

          }

           

          class LightOffCommand implements Command {

              Light light;

              LightOffCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.off();

              }

              public void undo() {

                  light.on();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

              public void undo() {

                  garageDoor.close();

              }

          }

           

          class GarageDoorCloseCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorCloseCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.close();

              }

              public void undo() {

                  garageDoor.open();

              }

          }

           

          class RemoteControl {

              Command[] onCommands;

              Command[] offCommands;

              Command noCommand = new noCommand();

              Command lastCommand;

              public RemoteControl() {

                  onCommands = new Command[7];

                  offCommands = new Command[7];

                  for (int i = 0; i < 7; i++) {

                      onCommands[i] = noCommand;

                      offCommands[i] = noCommand;

                  }

              }

              public void setControl(int slot, Command onCommand, Command offCommand) {

                  onCommands[slot] = onCommand;

                  offCommands[slot] = offCommand;

              }

              public void onButtonDown(int slot) {

                  onCommands[slot].execute();

                  lastCommand = onCommands[slot];

              }

              public void offButtonDown(int slot) {

                  offCommands[slot].execute();

                  lastCommand = offCommands[slot];

              }

              public void undoButtonDown() {

                  lastCommand.undo();

              }

          }

           

           

          這里有個問題,就是ConsecutiveCommand給寫死了,如果我還需要一個新的連續的命令組合,我就要編寫ConsecutiveCommand2ConsecutiveCommand3等等。能不能只寫一個,而實現動態配置呢?靠傳個參數告訴它要執行哪一串命令可以嗎?

          package javaapplication30;

           

          public class Main {

              public static void main(String[] args) {

                  Light light = new Light();

                  GarageDoor garageDoor = new GarageDoor();

                  Fan fan = new Fan();

                  RemoteControl rc = new RemoteControl();

           

                  Command fanHighCommand = new FanHighCommand(fan);

                  Command fanOffCommand = new FanOffCommand(fan);

                  Command garageDoorCloseCommand = new GarageDoorCloseCommand(garageDoor);

                  Command garageDoorOpenCommand = new GarageDoorOpenCommand(garageDoor);

                  Command lightOffCommand = new LightOffCommand(light);

                  Command lightOnCommand = new LightOnCommand(light);

           

                  Command[] commands = {lightOffCommand, fanOffCommand, garageDoorOpenCommand};

                  Command consecutiveCommands = new ConsecutiveCommands(commands);

                 

                  rc.setControl(0, fanHighCommand, fanOffCommand);

                  rc.setControl(1, garageDoorOpenCommand, garageDoorCloseCommand);

                  rc.setControl(2, lightOnCommand, lightOffCommand);       

                  rc.setControl(3, consecutiveCommands, null);

                 

                  for(int i=0;i<=3;i++)

                      rc.onButtonDown(i);

              }

          }

           

          class Light {

              public void on() {

                  System.out.println("turn Light on.");

              }

              void off() {

                  System.out.println("turn light off");

              }

          }

           

          class GarageDoor {

              public void open() {

                  System.out.println("open GarageDoor");

              }

              public void close() {

                  System.out.println("close GarageDoor");

              }

          }

           

          class Fan {

              public final int HIGH = 3;

              public final int MEDIUM = 2;

              public final int LOW = 1;

              public final int OFF = 0;

              public int speed = 0;

              public void high() {

                  speed = HIGH;

                  System.out.println("Fan's speed is " + speed);

              }

              public void low() {

                  speed = LOW;

                  System.out.println("Fan's speed is " + speed);

              }

              public void medium() {

                  speed = MEDIUM;

                  System.out.println("Fan's speed is " + speed);

              }

              public void off() {

                  speed = OFF;

                  System.out.println("Fan's speed is " + speed);

              }

              public int getSpeed() {

                  return speed;

              }

          }

           

          interface Command {

              public void execute();

              public void undo();

          }

           

          class noCommand implements Command {

              public void execute() {

                  System.out.println("no command here.");

              }

              public void undo() {

                  System.out.println("no command here.");

              }

          }

           

          abstract class FanCommand {

              Fan fan;

              int preSpeed;

              abstract void execute();

              public void undo() {

                  if (preSpeed == fan.HIGH) {

                      fan.high();

                  }

                  else if (preSpeed == fan.MEDIUM) {

                      fan.medium();

                  }

                  else if (preSpeed == fan.LOW) {

                      fan.low();

                  }

                  else if (preSpeed == fan.OFF) {

                      fan.off();

                  }

              }

          }

           

          class FanHighCommand extends FanCommand implements Command {

              FanHighCommand(Fan fan) {

                  super.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.high();

              }

          }

           

          class FanOffCommand extends FanCommand implements Command {

              FanOffCommand(Fan fan) {

                  super.fan = fan;

              }

              public void execute() {

                  preSpeed = fan.getSpeed();

                  fan.off();

              }

          }

           

          class ConsecutiveCommands implements Command {

              Command[] commands;

              ConsecutiveCommands(Command[] commands) {

                  this.commands = commands;

              }

              public void execute() {

                  for (int i = 0; i < commands.length; i++) {

                      commands[i].execute();

                  }

              }

              public void undo() {

                  for (int i = 0; i < commands.length; i++) {

                      commands[i].undo();

                  }

              }

          }

           

          class LightOnCommand implements Command {

              Light light;

              LightOnCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.on();

              }

              public void undo() {

                  light.off();

              }

          }

           

          class LightOffCommand implements Command {

              Light light;

              LightOffCommand(Light light) {

                  this.light = light;

              }

              public void execute() {

                  light.off();

              }

              public void undo() {

                  light.on();

              }

          }

           

          class GarageDoorOpenCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorOpenCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.open();

              }

              public void undo() {

                  garageDoor.close();

              }

          }

           

          class GarageDoorCloseCommand implements Command {

              GarageDoor garageDoor;

              GarageDoorCloseCommand(GarageDoor garageDoor) {

                  this.garageDoor = garageDoor;

              }

              public void execute() {

                  garageDoor.close();

              }

              public void undo() {

                  garageDoor.open();

              }

          }

           

          class RemoteControl {

              Command[] onCommands;

              Command[] offCommands;

              Command noCommand = new noCommand();

              Command lastCommand;

              public RemoteControl() {

                  onCommands = new Command[7];

                  offCommands = new Command[7];

                  for (int i = 0; i < 7; i++) {

                      onCommands[i] = noCommand;

                      offCommands[i] = noCommand;

                  }

              }

              public void setControl(int slot, Command onCommand, Command offCommand) {

                  onCommands[slot] = onCommand;

                  offCommands[slot] = offCommand;

              }

              public void onButtonDown(int slot) {

                  onCommands[slot].execute();

                  lastCommand = onCommands[slot];

              }

              public void offButtonDown(int slot) {

                  offCommands[slot].execute();

                  lastCommand = offCommands[slot];

              }

              public void undoButtonDown() {

                  lastCommand.undo();

              }

          }

           

           

          posted on 2008-07-02 11:26 化的了 閱讀(2374) 評論(4)  編輯  收藏 所屬分類: 設計模式

          Feedback

          # re: 命令模式 Command Pattern 2008-07-02 12:53 無羽蒼鷹
          感覺非常棒,收藏!  回復  更多評論
            

          # re: 命令模式 Command Pattern 2008-07-02 14:01 網賺
          b 不錯哈  回復  更多評論
            

          # re: 命令模式 Command Pattern 2008-09-26 10:59 skk
          Thank you!  回復  更多評論
            

          # re: 命令模式 Command Pattern[未登錄] 2010-04-16 18:14 cc
          nice article, but your English is not good enough.  回復  更多評論
            

          主站蜘蛛池模板: 门头沟区| 安达市| 南宁市| 禹城市| 汨罗市| 泰宁县| 托克逊县| 白山市| 西畴县| 广宗县| 乐亭县| 乌鲁木齐县| 舞钢市| 天全县| 濉溪县| 虹口区| 曲沃县| 嘉黎县| 绥滨县| 武安市| 南阳市| 西和县| 南雄市| 肇东市| 那坡县| 巴彦淖尔市| 固始县| 应用必备| 治多县| 凌海市| 化州市| 酒泉市| 额尔古纳市| 泸西县| 施甸县| 台东市| 昌平区| 阿拉尔市| 富平县| 自治县| 武定县|