久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C#設(shè)計(jì)模式(4)——抽象工廠模式

 賈朋亮博客 2014-11-11

一,、前言

  之前一直在忙于工作上的事情,關(guān)于設(shè)計(jì)模式系列一直沒更新,,最近項(xiàng)目中發(fā)現(xiàn),,對于設(shè)計(jì)模式的了解是必不可少的,當(dāng)然對于設(shè)計(jì)模式的應(yīng)用那更是重要,,可以說是否懂得應(yīng)用設(shè)計(jì)模式在項(xiàng)目中是衡量一個(gè)程序員的技術(shù)水平,,因?yàn)閷τ谝粋€(gè)功能的實(shí)現(xiàn),高級工程師和初級工程師一樣都會(huì)實(shí)現(xiàn),,但是區(qū)別在于它們實(shí)現(xiàn)功能的可擴(kuò)展和可維護(hù)性,,也就是代碼的是否“優(yōu)美”、可讀,。但是,,要更好地應(yīng)用,首先就必須了解各種設(shè)計(jì)模式和其應(yīng)用場景,,所以我還是希望繼續(xù)完成設(shè)計(jì)模式這個(gè)系列,,希望通過這種總結(jié)的方式來加深自己設(shè)計(jì)模式的理解。

二,、命令模式的介紹

2.1 命令模式的定義

命令模式屬于對象的行為型模式,。命令模式是把一個(gè)操作或者行為抽象為一個(gè)對象中,通過對命令的抽象化來使得發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分隔開,。命令模式的實(shí)現(xiàn)可以提供命令的撤銷和恢復(fù)功能,。

2.2 命令模式的結(jié)構(gòu)

  既然,命令模式是實(shí)現(xiàn)把發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分割開,,然而中間必須有某個(gè)對象來幫助發(fā)出命令者來傳達(dá)命令,,使得執(zhí)行命令的接收者可以收到命令并執(zhí)行命令。例如,,開學(xué)了,院領(lǐng)導(dǎo)說計(jì)算機(jī)學(xué)院要進(jìn)行軍訓(xùn),,計(jì)算機(jī)學(xué)院的學(xué)生要跑1000米,,院領(lǐng)導(dǎo)的話也就相當(dāng)于一個(gè)命令,,他不可能直接傳達(dá)給到學(xué)生,他必須讓教官來發(fā)出命令,,并監(jiān)督學(xué)生執(zhí)行該命令,。在這個(gè)場景中,發(fā)出命令的責(zé)任是屬于學(xué)院領(lǐng)導(dǎo),,院領(lǐng)導(dǎo)充當(dāng)與命令發(fā)出者的角色,,執(zhí)行命令的責(zé)任是屬于學(xué)生,學(xué)生充當(dāng)于命令接收者的角色,,而教官就充當(dāng)于命令的發(fā)出者或命令請求者的角色,,然而命令模式的精髓就在于把每個(gè)命令抽象為對象。從而命令模式的結(jié)構(gòu)如下圖所示:

從命令模式的結(jié)構(gòu)圖可以看出,,它涉及到五個(gè)角色,,它們分別是:

  • 客戶角色:發(fā)出一個(gè)具體的命令并確定其接受者。
  • 命令角色:聲明了一個(gè)給所有具體命令類實(shí)現(xiàn)的抽象接口
  • 具體命令角色:定義了一個(gè)接受者和行為的弱耦合,,負(fù)責(zé)調(diào)用接受者的相應(yīng)方法,。
  • 請求者角色:負(fù)責(zé)調(diào)用命令對象執(zhí)行命令。
  • 接受者角色:負(fù)責(zé)具體行為的執(zhí)行,。

2.3 命令模式的實(shí)現(xiàn)

  現(xiàn)在,,讓我們以上面的軍訓(xùn)的例子來實(shí)現(xiàn)一個(gè)命令模式,在實(shí)現(xiàn)之前,,可以參考下命令模式的結(jié)構(gòu)圖來分析下實(shí)現(xiàn)過程,。

  軍訓(xùn)場景中,具體的命令即是學(xué)生跑1000米,,這里學(xué)生是命令的接收者,,教官是命令的請求者,院領(lǐng)導(dǎo)是命令的發(fā)出者,,即客戶端角色,。要實(shí)現(xiàn)命令模式,則必須需要一個(gè)抽象命令角色來聲明約定,,這里以抽象類來來表示,。命令的傳達(dá)流程是:

  命令的發(fā)出者必須知道具體的命令、接受者和傳達(dá)命令的請求者,,對應(yīng)于程序也就是在客戶端角色中需要實(shí)例化三個(gè)角色的實(shí)例對象了,。

  命令的請求者負(fù)責(zé)調(diào)用命令對象的方法來保證命令的執(zhí)行,對應(yīng)于程序也就是請求者對象需要有命令對象的成員,,并在請求者對象的方法內(nèi)執(zhí)行命令,。

  具體命令就是跑1000米,這自然屬于學(xué)生的責(zé)任,所以是具體命令角色的成員方法,,而抽象命令類定義這個(gè)命令的抽象接口,。

  有了上面的分析之后,具體命令模式的實(shí)現(xiàn)代碼如下所示:

復(fù)制代碼
 1  
 2     // 教官,,負(fù)責(zé)調(diào)用命令對象執(zhí)行請求
 3     public class Invoke
 4     {
 5         public Command _command;
 6 
 7         public Invoke(Command command)
 8         {
 9             this._command = command;
10         }
11 
12         public void ExecuteCommand()
13         {
14             _command.Action();
15         }
16     }
17 
18     // 命令抽象類
19     public abstract class Command 
20     {
21         // 命令應(yīng)該知道接收者是誰,,所以有Receiver這個(gè)成員變量
22         protected Receiver _receiver;
23 
24         public Command(Receiver receiver)
25         {
26             this._receiver = receiver;
27         }
28 
29         // 命令執(zhí)行方法
30         public abstract void Action();
31     }
32 
33     // 
34     public class ConcreteCommand :Command
35     {
36         public ConcreteCommand(Receiver receiver)
37             : base(receiver)
38         { 
39         }
40 
41         public override void Action()
42         {
43             // 調(diào)用接收的方法,因?yàn)閳?zhí)行命令的是學(xué)生
44             _receiver.Run1000Meters();
45         }
46     }
47 
48     // 命令接收者——學(xué)生
49     public class Receiver
50     {
51         public void Run1000Meters()
52         {
53             Console.WriteLine("跑1000米");
54         }
55     }
56 
57     // 院領(lǐng)導(dǎo)
58     class Program
59     {
60         static void Main(string[] args)
61         {
62             // 初始化Receiver,、Invoke和Command
63             Receiver r = new Receiver();
64             Command c = new ConcreteCommand(r);
65             Invoke i = new Invoke(c);
66             
67             // 院領(lǐng)導(dǎo)發(fā)出命令
68             i.ExecuteCommand();
69         }
70     }
復(fù)制代碼

三,、.NET中命令模式的應(yīng)用(引用TerryLee)

在ASP.NET的MVC模式中,有一種叫Front Controller的模式,,它分為Handler和Command樹兩個(gè)部分,,Handler處理所有公共的邏輯,接收HTTP Post或Get請求以及相關(guān)的參數(shù)并根據(jù)輸入的參數(shù)選擇正確的命令對象,,然后將控制權(quán)傳遞到Command對象,,由其完成后面的操作,這里面其實(shí)就是用到了Command模式,。

    Front Controller 的處理程序部分結(jié)構(gòu)圖

    Front Controller的命令部分結(jié)構(gòu)圖

Handler 類負(fù)責(zé)處理各個(gè) Web 請求,,并將確定正確的 Command 對象這一職責(zé)委派給 CommandFactory 類。當(dāng) CommandFactory 返回 Command 對象后,,Handler 將調(diào)用 Command 上的 Execute 方法來執(zhí)行請求,。具體的實(shí)現(xiàn)如下

復(fù)制代碼
  1 // Handler類
  2 public class Handler : IHttpHandler
  3 
  4 {
  5     public void ProcessRequest(HttpContext context)
  6 
  7     {
  8 
  9         Command command = CommandFactory.Make(context.Request.Params);
 10 
 11         command.Execute(context);
 12 
 13     }
 14 
 15     public bool IsReusable
 16 
 17     {
 18         get
 19 
 20         {
 21             return true;
 22         }
 23     }
 24 }
 25 
 26 Command接口:
 27 /// <summary>
 28 /// Command
 29 /// </summary>
 30 public interface Command
 31 
 32 {
 33     void Execute(HttpContext context);
 34 }
 35 
 36 CommandFactory類:
 37 /// <summary>
 38 /// CommandFactory
 39 /// </summary>
 40 public class CommandFactory
 41 
 42 {
 43     public static Command Make(NameValueCollection parms)
 44 
 45     {
 46 
 47         string requestParm = parms["requestParm"];
 48 
 49         Command command = null;
 50 
 51         //根據(jù)輸入?yún)?shù)得到不同的Command對象
 52 
 53         switch (requestParm)
 54 
 55         {
 56             case "1":
 57 
 58                 command = new FirstPortal();
 59 
 60                 break;
 61 
 62             case "2":
 63 
 64                 command = new SecondPortal();
 65 
 66                 break;
 67 
 68             default:
 69 
 70                 command = new FirstPortal();
 71 
 72                 break;
 73         }
 74 
 75         return command;
 76 
 77     }
 78 }
 79 
 80 RedirectCommand類:
 81 public abstract class RedirectCommand : Command
 82 
 83 {
 84     //獲得Web.Config中定義的key和url鍵值對,UrlMap類詳見下載包中的代碼
 85 
 86     private UrlMap map = UrlMap.SoleInstance;
 87 
 88     protected abstract void OnExecute(HttpContext context);
 89 
 90     public void Execute(HttpContext context)
 91 
 92     {
 93         OnExecute(context);
 94 
 95         //根據(jù)key和url鍵值對提交到具體處理的頁面
 96 
 97         string url = String.Format("{0}?{1}", map.Map[context.Request.Url.AbsolutePath], context.Request.Url.Query);
 98 
 99         context.Server.Transfer(url);
100 
101     }
102 }
103 
104 FirstPortal類:
105 public class FirstPortal : RedirectCommand
106 
107 {
108     protected override void OnExecute(HttpContext context)
109 
110     {
111         //在輸入?yún)?shù)中加入項(xiàng)portalId以便頁面處理
112 
113         context.Items["portalId"] = "1";
114 
115     }
116 }
117 
118 SecondPortal類:
119 public class SecondPortal : RedirectCommand
120 
121 {
122     protected override void OnExecute(HttpContext context)
123 
124     {
125         context.Items["portalId"] = "2";
126     }
127 }
復(fù)制代碼

四,、命令模式的適用場景

  在下面的情況下可以考慮使用命令模式:

  1. 系統(tǒng)需要支持命令的撤銷(undo),。命令對象可以把狀態(tài)存儲(chǔ)起來,等到客戶端需要撤銷命令所產(chǎn)生的效果時(shí),,可以調(diào)用undo方法吧命令所產(chǎn)生的效果撤銷掉,。命令對象還可以提供redo方法,以供客戶端在需要時(shí),,再重新實(shí)現(xiàn)命令效果,。
  2. 系統(tǒng)需要在不同的時(shí)間指定請求、將請求排隊(duì),。一個(gè)命令對象和原先的請求發(fā)出者可以有不同的生命周期,。意思為:原來請求的發(fā)出者可能已經(jīng)不存在了,而命令對象本身可能仍是活動(dòng)的,。這時(shí)命令的接受者可以在本地,也可以在網(wǎng)絡(luò)的另一個(gè)地址,。命令對象可以串行地傳送到接受者上去,。
  3. 如果一個(gè)系統(tǒng)要將系統(tǒng)中所有的數(shù)據(jù)消息更新到日志里,以便在系統(tǒng)崩潰時(shí),,可以根據(jù)日志里讀回所有數(shù)據(jù)的更新命令,,重新調(diào)用方法來一條一條地執(zhí)行這些命令,從而恢復(fù)系統(tǒng)在崩潰前所做的數(shù)據(jù)更新,。
  4. 系統(tǒng)需要使用命令模式作為“CallBack(回調(diào))”在面向?qū)ο笙到y(tǒng)中的替代。Callback即是先將一個(gè)方法注冊上,,然后再以后調(diào)用該方法,。

五、命令模式的優(yōu)缺點(diǎn)

  命令模式使得命令發(fā)出的一個(gè)和接收的一方實(shí)現(xiàn)低耦合,,從而有以下的優(yōu)點(diǎn):

  • 命令模式使得新的命令很容易被加入到系統(tǒng)里,。
  • 可以設(shè)計(jì)一個(gè)命令隊(duì)列來實(shí)現(xiàn)對請求的Undo和Redo操作。
  • 可以較容易地將命令寫入日志,。
  • 可以把命令對象聚合在一起,,合成為合成命令。合成命令式合成模式的應(yīng)用,。

  命令模式的缺點(diǎn):

  • 使用命令模式可能會(huì)導(dǎo)致系統(tǒng)有過多的具體命令類,。這會(huì)使得命令模式在這樣的系統(tǒng)里變得不實(shí)際。

六,、總結(jié)

  命令模式的實(shí)現(xiàn)要點(diǎn)在于把某個(gè)具體的命令抽象化為具體的命令類,,并通過加入命令請求者角色來實(shí)現(xiàn)將命令發(fā)送者對命令執(zhí)行者的依賴分割開,在上面軍訓(xùn)的例子中,,如果不使用命令模式的話,,則命令的發(fā)送者將對命令接收者是強(qiáng)耦合的關(guān)系,實(shí)現(xiàn)代碼如下:

復(fù)制代碼
 1  // 院領(lǐng)導(dǎo)
 2     class Program
 3     {
 4         static void Main(string[] args)
 5         {
 6            // 行為的請求者和行為的實(shí)現(xiàn)者之間呈現(xiàn)一種緊耦合關(guān)系
 7             Receiver r = new Receiver();
 8 
 9             r.Run1000Meters();
10         }
11     }
12 
13     public class Receiver
14     {
15         // 操作
16         public void Run1000Meters()
17         {
18             Console.WriteLine("跑1000米");
19         }
20     }
復(fù)制代碼

  到這里,,本章的內(nèi)容就介紹結(jié)束了,在下一章將繼續(xù)為大家分享下我對迭代器模式的理解,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多