**定義:**命令模式(Command Pattern),將一個請求封閉成一個對象,從而使你可用不同的請求對客戶進行參數化;對請求排除或記錄請求日志,以及支持可撤銷的操作。
**類型:**行為型模式。
**概述:**
???????? 命令模式,被《Head?First設計模式》列為常見的設計模式之一,而且光看類圖,感覺很簡單。可是真正要去運用的時候,往往會發現無從下手。因為你不知道什么時候該使用命令模式。任何關聯的兩個類,你發現居然都可以使用命令模式。但是使用了之后,發現代碼理解起來似乎變得更復雜了。本來比較簡單,并且耦合并不嚴重的兩個類,再加進來一個命令類,反倒更復雜了。如果嚴格依照迪米特法則,差不多任何兩個有關聯的類都似乎需要一個中介類來減少它們的耦合。如果極端地這樣做,必將出現非常多的中介類,反倒將程序弄得更復雜了。
??????? 在代碼發展的初期,我們很難發現需要使用哪種模式。其實這個時候,我們也不必糾結該使用哪種模式,我們先把基本的對象抽象好就行了。待代碼發展到比較復雜開始需要重構代碼時,這個時候就是設計模式上場的時候了。重構代碼時,發現兩個類嚴重耦合,這個時候就得考慮使用何種方式解耦了。
??????? 創建型模式和結構型模式,更多地考慮代碼的復用,而行為型模式更多地考慮代碼的解耦。命令模式的作用,就是解耦的,主要解決那些“發出命令”和“響應命令”兩者之間的耦合。所謂術業有專攻,這句話在軟件設計體現得淋漓盡致。每個人都做自己擅長的事情,把不擅長的事情獨立出來,交給專門的人來做。
?????? 因為命令模式是抽象出命令的, 所以那些需要處理多次命令的,例如記錄,刪除,查找等操作命令的時候,就可以使用命令模式。
?????? 到處是點菜下訂單這樣的示例,雖然這是個非常好的應用命令模式的示例,但是被大家過多講述。所以這里,我舉一個新的示例。小機床作坊,老板(Boss)加10位操作工(A~J)的干活,主要生產螺絲、軸承等等。
**類圖:**
****
參與者:
1. Client,創建Boss、Workers以及具體的Command。
1. Boss,也即Invoker,調用命令。
1. ScrewCMD,BearingCMD,具體的命令,告訴Workers如何相應的生產。
1. Workers,也即Receiver,接收命令并響應具體的命令。
示例代碼:
~~~
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4
5 namespace CMD
6 {
7 abstract class Command
8 {
9 protected Workers workers;
10
11 public Command(Workers _workers)
12 {
13 this.workers = _workers;
14 }
15
16 abstract public void Execute();
17 }
18
19 class ScrewCMD : Command
20 {
21 public ScrewCMD(Workers _workers) : base(_workers) { }
22
23 public override void Execute()
24 {
25 workers.ProductScrew();
26 }
27 }
28
29 class BearingCMD : Command
30 {
31 public BearingCMD(Workers _workers) : base(_workers) { }
32
33 public override void Execute()
34 {
35 workers.ProductBearing();
36 }
37 }
38
39 class Workers
40 {
41 public void ProductScrew()
42 {
43 Console.WriteLine("生產螺絲!");
44 }
45
46 public void ProductBearing()
47 {
48 Console.WriteLine("生產軸承.");
49 }
50 }
51
52 class Boss
53 {
54 private Command command;
55
56 public void SetCommand(Command command)
57 {
58 this.command = command;
59 }
60
61 public void ExecuteCommand()
62 {
63 command.Execute();
64 }
65 }
66
67 class Program
68 {
69 static void Main(string[] args)
70 {
71 Workers workers = new Workers();
72 Command screw = new ScrewCMD(workers);
73 Command bearing = new BearingCMD(workers);
74 Boss boss = new Boss();
75
76 // 生產螺絲的命令
77 boss.SetCommand(screw);
78 boss.ExecuteCommand();
79
80 // 生產軸承的命令
81 boss.SetCommand(bearing);
82 boss.ExecuteCommand();
83
84 Console.Read();
85 }
86 }
87 }
~~~
適用性:
1. 抽象出待執行的動作以參數化某對象。
1. 在不同的時刻指定、排列和執行請求。
1. 支持取消操作
1. 支持修改日志,這樣當系統崩潰時,這些修改可以被重做一遍。
1. 用構建在原語操作上的高層操作構造一個系統。
優缺點:
1. 優點,降低命令發起者與命令接受者之間的耦合,將復雜的命令過程獨立出來。
1. 缺點,如果命令過多,管理命令本身會變得復雜起來。
參考資料:
1. 《設計模式——可復用面向對象軟件基礎》
1. 《大話設計模式》
1. 《Head?First設計模式》
- 前言
- 設計模式六大原則
- 1——創建型模式之簡單工廠模式
- 2——創建型模式之工廠方法模式
- 3——創建型模式之抽象工廠模式
- 4——創建型模式之單例模式
- 5——創建型模式之建造者模式
- 6——創建型模式之原型模式
- 7——結構型模式之適配器模式
- 8——結構型模式之橋接模式
- 9——結構型模式之組合模式
- 10——結構型模式之裝飾者模式
- 11——結構型模式之外觀模式
- 12——結構型模式之享元模式
- 13——結構型模式之代理模式
- 14——行為型模式之職責鏈模式
- 15——行為型模式之命令模式
- 16——行為型模式之解釋器模式
- 17——行為型模式之迭代器模式
- 18——行為型模式之中介者模式
- 19——行為型模式之備忘錄模式
- 20——行為型模式之觀察者模式
- 21——行為型模式之狀態模式
- 22——行為型模式之策略模式
- 23——行為型模式之模板方法模型
- 24——行為型模式之訪問者模式
- 設計模式總結