天天看點

java設計模式_指令模式 兩個不同風格的實作

 Command模式(指令)  Java深入到一定程度,就不可避免的碰到設計模式這一概念,了解設計模式,将使自己對java中的接口或抽象類應用有更深的了解.設計模式在java的中型系統中應用廣泛,遵循一定的程式設計模式,才能使自己的代碼便于了解,易于交流,Command(指令模式)模式是比較常用的一個模式.

   Command指令模式:Command模式通過被稱為Command的類封裝了對目标對象的調用行為以及調用參數。将一個請求封裝為一個對象,進而使你不同的請求對客戶進行參數化;對請求排隊或記錄請求日志,以及支援可撤銷的操作。

   優點:解耦了調用者和接受者之間聯系。調用者調用一個操作,接受者接受請求執行相應的動作,因為使用Command模式解耦,調用者無需知道接受者任何接口。

   缺點:造成出現過多的具體指令類

  在此寫了7個java類來描述說明Command設計模式的實作方式;

  1、Control.java       指令控制者對象類

  2、Tv.java            指令接收者對象類

  3、Command.java       指令接口類

  4、CommandChannel.java 頻道切換指令類

  5、CommandOff.java    關機指令類

  6、CommandOn.java     開機指令類

  7、CommandTest.java   帶有main方法的測試類(指令發送者)

===============  1、 Control.java

package command;

//指令控制者

public class Control {

  private Command onCommand, offCommand,changeChannel;

  public Control(Command on, Commandoff, Command channel) {

   onCommand = on;

   offCommand = off;

   changeChannel = channel;

  }

  public void turnOn() {

   onCommand.execute();

  }

  public void turnOff() {

   offCommand.execute();

  }

  public void changeChannel() {

   changeChannel.execute();

  }

}

===============   1end

===============  2、 Tv.java

package command;

//指令接收者

public class Tv {

  public int currentChannel = 0;

  public void turnOn() {

   System.out.println("The televisino is on.");

  }

  public void turnOff() {

   System.out.println("The television is off.");

  }

  public void changeChannel(int channel){

   this.currentChannel = channel;

   System.out.println("Now TV channel is " + channel);

  }

}

===============   2end

===============  3、 Command.java

package command;

//指令接口

public interface Command {

  void execute();

}

===============   3end

===============  4、 CommandChannel.java

package command;

//頻道切換指令

public class CommandChannel implements Command {

  private Tv myTv;

  private int channel;

  public CommandChannel(Tv tv, intchannel) {

   myTv = tv;

   this.channel = channel;

  }

  public void execute() {

   myTv.changeChannel(channel);

  }

}

===============   4end

===============  5、 CommandOff.java

package command;

//關機指令

public class CommandOff implements Command {

  private Tv myTv;

  public CommandOff(Tv tv) {

   myTv = tv;

  }

  public void execute() {

   myTv.turnOff();

  }

}

===============   5end

===============  6、 CommandOn.java

package command;

//開機指令

public class CommandOn implements Command {

  private Tv myTv;

  public CommandOn(Tv tv) {

   myTv = tv;

  }

  public void execute() {

   myTv.turnOn();

  }

}

===============   6end

===============  7、 CommandTest.java

package command;

//指令發送者

public class CommandTest{

  public static void main(String[]args){

   //指令接收者

   Tv  myTv = new Tv();

   //開機指令

   CommandOn on = new CommandOn(myTv);

   //關機指令

   CommandOff off = new CommandOff(myTv);

   //頻道切換指令

   CommandChannel channel = new CommandChannel(myTv, 2);

   //指令控制對象

   Control control = new Control( on, off, channel);

   //開機

   control.turnOn();

   //切換頻道

   control.changeChannel();

   //關機

   control.turnOff();

  }

}

===============   7end

  Command模式通常可應用到以下場景:

  1 Multi-levelundo(多級undo操作)

   如果系統需要實作多級回退操作,這時如果所有使用者的操作都以command對象的形式實作,系統可以簡

   單地用stack來儲存最近執行的指令,如果使用者需要執行undo操作,系統隻需簡單地popup一個最近的

   command對象然後執行它的undo()方法既可。

  2 Transactionalbehavior(原子事務行為)

   借助command模式,可以簡單地實作一個具有原子事務的行為。當一個事務失敗時,往往需要回退到執

   行前的狀态,可以借助command對象儲存這種狀态,簡單地處理回退操作。

3 Progressbars(狀态條)

   假如系統需要按順序執行一系列的指令操作,如果每個command對象都提供一個

   getEstimatedDuration()方法,那麼系統可以簡單地評估執行狀态并顯示出合适的狀态條。

4 Wizards(導航)

   通常一個使用多個wizard頁面來共同完成一個簡單動作。一個自然的方法是使用一個command對象來封

   裝wizard過程,該command對象在第一個wizard頁面顯示時被建立,每個wizard頁面接收使用者輸入并設

   置到該command對象中,當最後一個wizard頁面使用者按下“Finish”按鈕時,可以簡單地觸發一個事件

   調用execute()方法執行整個動作。通過這種方法,command類不包含任何跟使用者界面有關的代碼,可以

   分離使用者界面與具體的處理邏輯。

5 GUI buttons andmenu items(GUI按鈕與菜單條等等)

   Swing系統裡,使用者可以通過工具條按鈕,菜單按鈕執行指令,可以用command對象來封裝指令的執行。

6 Threadpools(線程池)

   通常一個典型的線程池實作類可能有一個名為addTask()的public方法,用來添加一項工作任務到任務

   隊列中。該任務隊列中的所有任務可以用command對象來封裝,通常這些command對象會實作一個通用的

   接口比如java.lang.Runnable。

7 Macrorecording(宏紀錄)

   可以用command對象來封裝使用者的一個操作,這樣系統可以簡單通過隊列儲存一系列的command對象的狀

   态就可以記錄使用者的連續操作。這樣通過執行隊列中的command對象,就可以完成"Play back"操作了。

8 Networking

   通過網絡發送command指令到其他機器上運作。

9 ParallelProcessing(并發處理)

   當一個調用共享某個資源并被多個線程并發處理時。

執行個體二:

package command2;

public class AddRequirementCommand extends Command {

     //執行增加一項需求的指令

     public void execute() {

      //找到需求組

      super.rg.find();

      //增加一份需求

      super.rg.add();

      //給出計劃

      super.rg.plan();

     }

    }

----------------------------------------------------------

package command2;

public class Client {

     public static void main(String[] args) {

      //定義我們的接頭人

        Invoker xiaoSan = newInvoker();  //接頭人就是我小三

       //客戶要求增加一項需求

       System.out.println("-------------客戶要求增加一項需求-----------------");

       //客戶給我們下指令來

        Command command = newAddRequirementCommand();

       //接頭人接收到指令

        xiaoSan.setCommand(command);

       //接頭人執行指令

        xiaoSan.action();

     }

    }

   ------------------------------------------------------------------

package command2;

public class CodeGroup extends Group {

  //客戶要求代碼組過去和他們談

  public void find() {

   System.out.println("找到代碼組...");

  }

  //客戶要求增加一項功能

  public void add() {

   System.out.println("客戶要求增加一項功能...");

  }

//客戶要求修改一項功能

  public void change() {