Java設計模式——Command模式(容易,次要)

轉自: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模式解耦,調用者無需知道接受者任何接口。 
     缺點: 造成出現過多的具體命令類 

代碼例子如下: 

播放器執行命令者: 

Java代碼  收藏代碼
  1. package command;  
  2.   
  3. //命令執行者播放器  
  4. public class Player {  
  5.   
  6.     public void turnOn(){  
  7.           
  8.         System.out.println("打開");  
  9.     }  
  10.       
  11.     public void turnOff(){  
  12.         System.out.println("關閉");  
  13.           
  14.     }  
  15.       
  16.     public void next(){  
  17.           
  18.         System.out.println("下一曲");  
  19.     }  
  20. }  
    

命令接口: 
Java代碼  收藏代碼
  1. package command;  
  2.   
  3. public interface Command {  
  4.   
  5.     public void execute();  
  6. }  


各種命令實現類: 
Java代碼  收藏代碼
  1. package command;  
  2. //打開命令類  
  3. public class TurnOnCommand implements Command {  
  4.   
  5.     private Player player;  
  6.       
  7.     public TurnOnCommand(Player player) {  
  8.         this.player = player;  
  9.     }  
  10.       
  11.     public void execute() {  
  12.         this.player.turnOn();  
  13.     }  
  14.   
  15. }  
  16.   
  17.   
  18. package command;  
  19. //關閉命令類  
  20. public class TurnOffCommand implements Command {  
  21.   
  22. private Player player;  
  23.       
  24.     public TurnOffCommand(Player player) {  
  25.         this.player = player;  
  26.     }  
  27.       
  28.     public void execute() {  
  29.         this.player.turnOff();  
  30.     }  
  31.   
  32. }  
  33.   
  34.   
  35. package command;  
  36. //下一曲命令類  
  37. public class NextCommand implements Command {  
  38.   
  39. private Player player;  
  40.       
  41.     public NextCommand(Player player) {  
  42.         this.player = player;  
  43.     }  
  44.       
  45.     public void execute() {  
  46.         this.player.next();  
  47.     }  
  48.   
  49. }  


命令發送者類: 
Java代碼  收藏代碼
  1. package command;  
  2. //命令發送類  
  3. public class PlayerInvoker {  
  4.   
  5.     private TurnOnCommand on;  
  6.     private TurnOffCommand off;  
  7.     private NextCommand next;  
  8.     public PlayerInvoker(TurnOnCommand on,TurnOffCommand off,NextCommand next) {  
  9.         this.on = on;  
  10.         this.off = off;  
  11.         this.next = next;  
  12.     }  
  13.       
  14.     public void turnOn(){         
  15.         this.on.execute();  
  16.     }  
  17.       
  18.     public void turnOff(){        
  19.         this.off.execute();  
  20.     }  
  21.       
  22.     public void next(){       
  23.         this.next.execute();  
  24.     }  
  25. }  


測試類: 
Java代碼  收藏代碼
  1. package command;  
  2. //測試類  
  3. public class Text {  
  4.       
  5. public static void main(String[] args) {  
  6.       
  7.     Player player = new Player();  
  8.     TurnOnCommand  on = new TurnOnCommand(player);  
  9.     TurnOffCommand  off = new TurnOffCommand(player);  
  10.     NextCommand  next = new NextCommand(player);  
  11.       
  12.     PlayerInvoker invoker = new PlayerInvoker(on, off, next);  
  13.       
  14.     invoker.turnOn();  
  15.     invoker.turnOff();  
  16.     invoker.next();  
  17. }  
  18. }  


    顯然這樣做的好處是符合封裝的特性,降低耦合度,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(併發處理) 
    當一個調用共享某個資源並被多個線程併發處理時。 



 



發佈了71 篇原創文章 · 獲贊 208 · 訪問量 81萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章