国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

.NET中的設計模式四:命令模式

2024-07-10 12:56:40
字體:
來源:轉載
供稿:網友
命令模式(command)結構并不復雜,簡單的說,就是將某些職責封裝成對象,對象的激發者(invoker)和接收者(reciever)都不過問命令的執行過程。用這樣的方式解除了激發者和接受者之間的耦合,為程序提供了更清晰的層次結構。實際運用中經常是將系統中的命令抽象成一個接口,所有的命令都是這個接口的實現,如下所示:


command類是icommand的實現,command類實現了execute方法,其他命令類都是command方法的子類。這樣激發者接受者和接受者面臨的環境就非常簡單了:統一作為command類型就可以處理了。

最簡單的命令模式的實現代碼如下:

///定義command接口

public interface icommand

{

void execute();

}



///實現icommand接口

///command類是所有命令的基類,在這里實現一些命令的共同處理過程

public abstract class command : icommand

{

public virtual void execute()

{

}

//實現其他的方法....

}



///實現一個具體的command1

public class command1 : command

{

public void override execute()

{

//具體的處理過程

}

}



///實現一個具體的command2

public class command2 : command

{

public void override execute()

{

//具體的處理過程

}

}



///實現一個具體的command3

public class command3 : command

{

public void override execute()

{

//具體的處理過程

}

}


命令模式的實際應用

下面從一個系統實例看一看命令模式的應用。reportingservice是一個報表系統的一部分,是一個運行在windows系統上的service程序,所需要完成的功能是:每天晚上11點到凌晨2點,將數據庫中的大批量的數據生成數百張報表。報表的分布較為復雜,有的要求在web服務器上發布報表,有的要求將報表數據輸出成一個文本文件,還有的要將報表保存在數據庫系統中。

系統的設計運用了命令模式,其中的一部分結構如下:



程序中定義了icommand接口,實現了多個command類(這里只畫出3個表示示例),分別執行各個報表的生成任務。command類提供了下列接口:

分類 名稱 類型 說明
屬性 finished bool 表示任務是否已經進行完畢
屬性 context iapplicationcontext 任務執行需要的環境和資源,包括數據庫連接、文件系統等等
方法 execute void 執行任務

service的主線程每天定時將系統運行環境進行初始化,建立一個applicationcontext類的實例(application是一個singlton模式的類,圖中沒有體現),這個類中保存了command運行需要使用的全部資源。然后初始化一個command對象列表,逐個執行每一個command。這樣一來,復雜的業務邏輯就從程序的主框架中分離開了,service的主線程所需要做的全部工作就是協調資源的分配和異常的處理,還可以不斷檢查命令執行的狀態,看看finished屬性是否為真。如果執行完以后發現某些命令執行不成功,要做相應的處理。

程序采用了單元測試的開發方式,在對程序主線程進行測試的時候,使用了一個虛擬的command實現。測試每一個command類的時候則為每個command實現了虛擬的applicationcontext。這樣的結構為單元測試提供了很多便利。關于提高程序的可測試性可以參見我的另一篇文章:怎樣測試代碼中難測試的部分。

命令模式和其他模式的結合

為了給command的建立提供一個整潔簡單的方式,command模式經常和工廠模式(factory)結合使用,采用一個工廠對command對象的建立進行管理,減少命令激發者與命令對象之間的耦合程度。

在窗體程序中,command模式還經常與組合模式(composition)結合使用。可以在初始化窗體的時候,將畫面上的菜單項、工具欄、按鈕等控件與相應的command進行組合,這樣在控件點擊時,調用對應的command,即可實現對命令的處理。

在《程序員》雜志本年第10月期介紹了一個利用command模式實現程序中undo功能的文章。程序中為每個command定義了“執行”和“撤銷”兩種操作,如下:



圖中的action就是commamnd對象,只是名稱不同,意義是一樣的。action對象存在do和undo方法,分別是“執行”和“撤銷”方法。可以將執行完畢的action對象的done屬性設置為true,再將其保存在一個列表中——actionlist。在actionlist中找到最后一個done屬性為true的action,執行其undo方法,即可實現“撤銷”的操作。

命令類的序列化

如果將command基類及其每一個子類都進行序列化,可以實現更多的強大的功能。程序執行過程中,如果發生異常,比如網絡發生中斷、文件丟失等異常,可以將沒有執行完畢的command序列化保存下來。等待可以執行的時候再將這些對象重新加載,命令可以繼續執行。甚至用戶已經重新啟動了計算機,命令也可以繼續執行。command對象的序列化也為分布式的操作提供了便利。在網絡環境中,可以在某處建立一個command對象,將其序列化后傳輸到網絡上另一臺計算機上進行執行。這種情況下不要忘記異常類的序列化,如果自己定義了exception的子類,也要將其進行序列化,以便在網絡環境中捕捉和處理command執行時發生的異常。microsoft網站上有一篇文章介紹.net中對象的序列化,詳細的介紹了對象序列化的概念。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 梁河县| 鲁山县| 三都| 尼玛县| 格尔木市| 乌兰县| 石泉县| 富裕县| 临洮县| 民县| 麻栗坡县| 左权县| 南乐县| 临猗县| 体育| 吉隆县| 洪江市| 韶山市| 集贤县| 临洮县| 朔州市| 南皮县| 武冈市| 平果县| 通渭县| 阳原县| 呼伦贝尔市| 启东市| 湘潭市| 甘德县| 西贡区| 静乐县| 格尔木市| 兴义市| 枝江市| 秦皇岛市| 广德县| 汝阳县| 广安市| 保靖县| 禄劝|