設計模式之Command

Command 模式是最讓我疑惑的一個模式 , 我在閱讀了很多代碼後 , 才感覺隱約掌握其大概原理 , 我認爲理解設計模式最主要是掌握起原理構造 , 這樣才對自己實際編程有指導作用。 Command 模式實際上不是個很具體 , 規定很多的模式 , 正是這個靈活性 , 讓人有些 confuse

Command 定義
不少 Command 模式的代碼都是針對圖形介面的 , 它實際就是功能表命令 , 我們在一個下拉功能表選擇一個命令時 , 然後會執行一些動作。

將這些命令封裝成在一個類別中 , 然後用戶 ( 呼叫者 ) 再對這個類別進行操作 , 這就是 Command 模式 , 換句話說 , 本來用戶 ( 呼叫者 ) 是直接呼叫這些命令的 , 如功能表上打開文檔 ( 呼叫者 ), 就直接指向打開文檔的代碼 , 使用 Command 模式 , 就是在這兩者之間增加一個中間者 , 將這種直接關係拗斷 , 同時兩者之間都隔離 , 基本沒有關係了。

顯然這樣做的好處是符合封裝的特性 , 降低耦合度 ,Command 是將對行爲進行封裝的典型模式 ,Factory 是將創建進行封裝的模式 ,
Command 模式 , 我也發現設計模式一個 " 通病 ": 好象喜歡將簡單的問題複雜化 , 喜歡在不同類別中增加第三者 , 當然這樣做有利於代碼的健壯性 可維護性 還有複用性。

如何使用 ?
具體的 Command 模式代碼各式各樣 , 因爲如何封裝命令 , 不同系統 , 有不同的做法。下面事例是將命令封裝在一個 CollectionList, 任何物件一旦加入 List, 實際上裝入了一個封閉的黑盒中 , 物件的特性消失了 , 只有取出時 , 才有可能模糊的分辨出 :

典型的 Command 模式需要有一個介面。介面中有一個統一的方法 , 這就是 " 將命令 / 請求封裝爲物件 ":

public interface Command {
   public abstract void execute ( );
}


具體不同命令 / 請求代碼是實現介面 Command, 下面有三個具體命令

public class Engineer implements Command {

  
public void execute( ) {
    
//do Engineer's command
   }
}

public class Programmer implements Command {

  
public void execute( ) {
    
//do programmer's command
   }
}

public class Politician implements Command {

  
public void execute( ) {
    
//do Politician's command
   }
}

 

按照通常做法 , 我們就可以直接呼叫這三個 Command, 但是使用 Command 模式 , 我們要將他們封裝起來 , 扔到黑盒子 List 裏去 :

public class producer{
   public static List produceRequests() {
     List queue = new ArrayList();
     queue.add( new DomesticEngineer() );
     queue.add( new Politician() );
     queue.add( new Programmer() );
     return queue;
   }

}

這三個命令進入 List 中後 , 已經失去了其外表特徵 , 以後再取出 , 也可能無法分辨出誰是 Engineer 誰是 Programmer, 看下面如何呼叫 Command 模式 :

public class TestCommand {
   public static void main(String[] args) {
    
     List queue = Producer.produceRequests();
     for (Iterator it = queue.iterator(); it.hasNext(); )
         // 取出 List 中東東 , 其他特徵都不能確定 , 只能保證一個特徵是 100% 正確 ,
         // 他們至少是介面 Command" 兒子 " 。所以強制轉換類別型爲介面 Command

         ((Command)it.next()).execute();
  

   }
}

由此可見 , 呼叫者基本只和介面打交道 , 不合具體實現交互 , 這也體現了一個原則 , 面向介面編程 , 這樣 , 以後增加第四個具體命令時 , 就不必修改呼叫者 TestCommand 中的代碼了。

理解了上面的代碼的核心原理 , 在使用中 , 就應該各人有自己方法了 , 特別是在如何分離呼叫者和具體命令上 , 有很多實現方法 , 上面的代碼是使用 "List 過一遍 " 的做法。這種做法只是爲了演示。

使用 Command 模式的一個好理由還因爲它能實現 Undo 功能。每個具體命令都可以記住它剛剛執行的動作 , 並且在需要時恢復。

Command 模式在介面設計中應用廣泛。 JavaSwing 中功能表命令都是使用 Command 模式 , 由於 Java 在介面設計的性能上還有欠缺 , 因此介面設計具體代碼我們就不討論 , 網路上有很多這樣的示例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值