Java之命令模式(Command Pattern)

來源:互聯網
上載者:User

1.概念

  將來自用戶端的請求傳入一個對象,從而使你可用不同的請求對客戶進行參數化。用於“行為要求者”與“行為實現者”解耦,可實現二者之間的松耦合,以便適應變化。分離變化與不變的因素。

   在物件導向的程式設計中,一個對象調用另一個對象,一般情況下的調用過程是:建立目標對象執行個體;設定調用參數;調用目標對象的方法。

但在有些情況下有必要使用一個專門的類對這種調用過程加以封裝,我們把這種專門的類稱作command類。

Command模式可應用於
a)整個調用過程比較繁雜,或者存在多處這種調用。這時,使用Command類對該調用加以封裝,便於功能的再利用。
b)調用前後需要對調用參數進行某些處理。
c)調用前後需要進行某些額外處理,比如日誌,緩衝,記錄曆史操作等。

Command模式有如下效果:
a)將叫用作業的對象和知道如何?該操作的對象解耦。
b)Command是頭等對象。他們可以像其他對象一樣被操作和擴充。
c)你可將多個命令裝配成一個符合命令。
d)增加新的Command很容易,因為這無需改變現有的類。

 

2.UML

3.代碼

public interface Command {
public void execute();
}


public class ConcreteCommand implements Command {

private Receiver receiver = null;
private String state;

public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
public void execute() {
receiver.action();
}
}


public class Receiver {
public void action(){
//真正執行命令操作的功能代碼
}
}


public class Invoker {
private Command command = null;

public void setCommand(Command command) {
this.command = command;
}

public void runCommand() {
command.execute();
}
}

public class Client {
public void assemble(){
//建立接收者
Receiver receiver = new Receiver();
//建立命令對象,設定它的接收者
Command command = new ConcreteCommand(receiver);
//建立Invoker,把命令對象設定進去
Invoker invoker = new Invoker();
invoker.setCommand(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);
  }
}

//執行命令的介面
public interface Command {
  void execute();
}

//開機命令
public class CommandOn implements Command {
  private Tv myTv;

  public CommandOn(Tv tv) {
   myTv = tv;
  }

  public void execute() {
   myTv.turnOn();
  }
}

//關機命令
public class CommandOff implements Command {
  private Tv myTv;

  public CommandOff(Tv tv) {
   myTv = tv;
  }

  public void execute() {
   myTv.turnOff();
  }
}

//頻道切換命令
public class CommandChange implements Command {
  private Tv myTv;

  private int channel;

  public CommandChange(Tv tv, int channel) {
   myTv = tv;
   this.channel = channel;
  }

  public void execute() {
   myTv.changeChannel(channel);
  }
}

//可以看作是遙控器吧
public class Control {
  private Command onCommand, offCommand, changeChannel;

  public Control(Command on, Command off, Command channel) {
   onCommand = on;
   offCommand = off;
   changeChannel = channel;
  }

  public void turnOn() {
   onCommand.execute();
  }

  public void turnOff() {
   offCommand.execute();
  }

  public void changeChannel() {
   changeChannel.execute();
  }
}

//測試類別
public class Client {
  public static void main(String[] args) {
   // 命令接收者
   Tv myTv = new Tv();
   // 開機命令
   CommandOn on = new CommandOn(myTv);
   // 關機命令
   CommandOff off = new CommandOff(myTv);
   // 頻道切換命令
   CommandChange channel = new CommandChange(myTv, 2);
   // 命令控制對象
   Control control = new Control(on, off, channel);

   // 開機
   control.turnOn();
   // 切換頻道
   control.changeChannel();
   // 關機
   control.turnOff();
  }
}


執行結果為:
The televisino is on.
Now TV channel is 2
The television is off.

4.應用情境

在下面的情況下應當考慮使用命令模式:

1)使用命令模式作為"CallBack"在物件導向系統中的替代。"CallBack"講的便是先將一個函數登記上,然後在以後調用此函數。

2)需要在不同的時間指定請求、將請求排隊。一個命令對象和原先的請求發出者可以有不同的生命期。換言之,原先的請求發出者可能已經不在了,而命令對象本身仍然是活動的。這時命令的接收者可以是在本地,也可以在網路的另外一個地址。命令對象可以在串形化之後傳送到另外一台機器上去。

3)系統需要支援命令的撤消(undo)。命令對象可以把狀態儲存起來,等到用戶端需要撤銷命令所產生的效果時,可以調用undo()方法,把命令所產生的效果撤銷掉。命令對象還可以提供redo()方法,以供用戶端在需要時,再重新實施命令效果。

4)如果一個系統要將系統中所有的資料更新到日誌裡,以便在系統崩潰時,可以根據日誌裡讀回所有的資料更新命令,重新調用Execute()方法一條一條執行這些命令,從而恢複系統在崩潰前所做的資料更新。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.