轉自:http://www.cnblogs.com/shamgod/p/4593772.html
一、概述
命令模式:客戶端對服務器端發出各種命令
二、代碼
1.Client.java
1 public class Client { 2 3 public void request(Server server){ 4 server.addCommand(new TextCommand()); 5 server.addCommand(new ImageCommand()); 6 server.doSomething(); 7 } 8 }
2.Server.java
1 public class Server { 2 3 private List<Command> commands = new ArrayList<Command>(); 4 5 public void doSomething() { 6 for(Command c : commands){ 7 c.execute(); 8 } 9 } 10 11 public void addCommand(Command command) { 12 commands.add(command); 13 } 14 15 }
3.Command.java
1 public abstract class Command { 2 3 public abstract void execute(); 4 public abstract void unDo(); 5 6 }
4.TextCommand.java
1 public class TextCommand extends Command { 2 3 @Override 4 public void execute() { 5 System.out.println("TextCommand..........."); 6 } 7 8 @Override 9 public void unDo() { 10 // 涉及到操作的歷史記錄 11 } 12 13 }
5.ImageCommand.java
1 public class ImageCommand extends Command { 2 3 @Override 4 public void execute() { 5 System.out.println("ImageCommand..........."); 6 } 7 8 @Override 9 public void unDo() { 10 // 涉及到操作的歷史記錄 11 } 12 13 }
6.Test.java
1 public class Test { 2 3 @org.junit.Test 4 public void test(){ 5 Client c = new Client(); 6 c.request(new Server()); 7 } 8 9 }
三、運行結果
轉自:http://men4661273.iteye.com/blog/1633775
Command定義
將一個請求封裝爲一個對象,從而可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可取消的操作。
優點: 解耦了調用者和接受者之間聯繫。調用者調用一個操作,接受者接受請求執行相應的動作,因爲使用Command模式解耦,調用者無需知道接受者任何接口。
缺點: 造成出現過多的具體命令類
代碼例子如下:
播放器執行命令者:
- package command;
- //命令執行者播放器
- public class Player {
- public void turnOn(){
- System.out.println("打開");
- }
- public void turnOff(){
- System.out.println("關閉");
- }
- public void next(){
- System.out.println("下一曲");
- }
- }
命令接口:
- package command;
- public interface Command {
- public void execute();
- }
各種命令實現類:
- package command;
- //打開命令類
- public class TurnOnCommand implements Command {
- private Player player;
- public TurnOnCommand(Player player) {
- this.player = player;
- }
- public void execute() {
- this.player.turnOn();
- }
- }
- package command;
- //關閉命令類
- public class TurnOffCommand implements Command {
- private Player player;
- public TurnOffCommand(Player player) {
- this.player = player;
- }
- public void execute() {
- this.player.turnOff();
- }
- }
- package command;
- //下一曲命令類
- public class NextCommand implements Command {
- private Player player;
- public NextCommand(Player player) {
- this.player = player;
- }
- public void execute() {
- this.player.next();
- }
- }
命令發送者類:
- package command;
- //命令發送類
- public class PlayerInvoker {
- private TurnOnCommand on;
- private TurnOffCommand off;
- private NextCommand next;
- public PlayerInvoker(TurnOnCommand on,TurnOffCommand off,NextCommand next) {
- this.on = on;
- this.off = off;
- this.next = next;
- }
- public void turnOn(){
- this.on.execute();
- }
- public void turnOff(){
- this.off.execute();
- }
- public void next(){
- this.next.execute();
- }
- }
測試類:
- package command;
- //測試類
- public class Text {
- public static void main(String[] args) {
- Player player = new Player();
- TurnOnCommand on = new TurnOnCommand(player);
- TurnOffCommand off = new TurnOffCommand(player);
- NextCommand next = new NextCommand(player);
- PlayerInvoker invoker = new PlayerInvoker(on, off, next);
- invoker.turnOn();
- invoker.turnOff();
- invoker.next();
- }
- }
顯然這樣做的好處是符合封裝的特性,降低耦合度,Command 是將對行爲進行封裝的典型模式,這樣做有利於代碼的健壯性 可維護性 還有複用性.
Command模式通常可應用到以下場景:
1 Multi-level undo(多級undo操作)
如果系統需要實現多級回退操作,這時如果所有用戶的操作都以command對象的形式實現,系統可以簡
單地用stack來保存最近執行的命令,如果用戶需要執行undo操作,系統只需簡單地popup一個最近的
command對象然後執行它的undo()方法既可。
2 Transactional behavior(原子事務行爲)
藉助command模式,可以簡單地實現一個具有原子事務的行爲。當一個事務失敗時,往往需要回退到執
行前的狀態,可以藉助command對象保存這種狀態,簡單地處理回退操作。
3 Progress bars(狀態條)
假如系統需要按順序執行一系列的命令操作,如果每個command對象都提供一個
getEstimatedDuration()方法,那麼系統可以簡單地評估執行狀態並顯示出合適的狀態條。
4 Wizards(導航)
通常一個使用多個wizard頁面來共同完成一個簡單動作。一個自然的方法是使用一個command對象來封
裝wizard過程,該command對象在第一個wizard頁面顯示時被創建,每個wizard頁面接收用戶輸入並設
置到該command對象中,當最後一個wizard頁面用戶按下“Finish”按鈕時,可以簡單地觸發一個事件
調用execute()方法執行整個動作。通過這種方法,command類不包含任何跟用戶界面有關的代碼,可以
分離用戶界面與具體的處理邏輯。
5 GUI buttons and menu items(GUI按鈕與菜單條等等)
Swing系統裏,用戶可以通過工具條按鈕,菜單按鈕執行命令,可以用command對象來封裝命令的執行。
6 Thread pools(線程池)
通常一個典型的線程池實現類可能有一個名爲addTask()的public方法,用來添加一項工作任務到任務
隊列中。該任務隊列中的所有任務可以用command對象來封裝,通常這些command對象會實現一個通用的
接口比如java.lang.Runnable。
7 Macro recording(宏紀錄)
可以用command對象來封裝用戶的一個操作,這樣系統可以簡單通過隊列保存一系列的command對象的狀
態就可以記錄用戶的連續操作。這樣通過執行隊列中的command對象,就可以完成"Play back"操作了。
8 Networking
通過網絡發送command命令到其他機器上運行。
9 Parallel Processing(併發處理)
當一個調用共享某個資源並被多個線程併發處理時。