程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 用設計模式固化你的C#程序(1)

用設計模式固化你的C#程序(1)

編輯:C#入門知識

用設計模式固化你的C#程序(1)

Design Patterns: Solidify Your C# Application Architecture with Design Patterns中文版(上篇)

作者:Samir Bajaj
譯者:榮耀

【譯序:C#進階文章。譯者對Samir提供的C#例子進行了簡單整理(作者提供的某些代碼在譯者的環境中無法通過編譯),並編寫了對應的C++示例,一並置於譯注中,以便讀者比對。譯文中所有C#、C++程序調試環境均為Microsoft Visual Studio.NET 7.0 Beta2】

【概要:通過提供一個框架,設計模式可以解決應用開發中的許多問題。模式使得設計過程更加清晰高效,它特別適用於C#程序開發,因為C#是面向對象的語言。【譯注:因為設計模式的由來和出發點就是描述面向對象的(可復用的)軟件設計】現有的設計模式為你自己的類的設計提供了優秀的模板,使用模式可以縮短軟件開發周期。本文將描述幾個流行的設計模式,包括singleton、strategy、decorator、composite和state,你可以在你自己的應用中使用它們,藉此提高應用的擴展性,並使類更易於重用。】

  正如任何一個老練的面向對象的軟件開發者所了解的那樣,缺乏對設計模式最起碼的了解而來討論軟件設計架構是不可思議的。如果不是全部那也有大多數的軟件應用、工具和系統至少使用了一種甚至更多種設計模式。設計模式是一種對一套相互作用的類的描述,這些類為解決特定上下文環境中的一般性問題提供了框架。換句話說,模式為面向對象軟件開發中的特定問題提供了解決方案。此外,模式一般也重視限制其適應解決方案的相關約束和其它因素。類和類之間的連接和通信以及上下文細節共同定義了一個模式,它為任何一個面向對象軟件設計中在特性和必要條件方面與之匹配的問題提供了解決方案。

  我必須承認我是設計模式的一個熱心的支持者。自從我閱讀了Gamma、Helm、Johnson和Vlissides合著的那本創造性的著作《設計模式》以來,我就很少不用任何模式而設計軟件了。實際上,我在軟件設計的早期階段花了相當可觀的時間來定奪可和將來架構自然吻合的模式。畢竟,模式是經過時間和應用領域考驗過的對一些問題的解決方案,那些問題已經被經驗豐富的設計師、開發者和語言專家所解決。對任何一個正在進行軟件設計的人員來說,善用可加以利用的知識和專家經驗是明智的。而采用一個已被反復證明是成功的解決方案而不是從頭發明一個新的往往是個好主意。

  幾乎沒有開發人員能夠享受只寫小程序的奢侈了。現代的應用軟件和系統是復雜的,它們往往由成千上萬行代碼組成,並且在這些基礎代碼之上的代碼甚至更為龐大。僅僅對工具和語言的簡單掌握是不足以勝任程序設計要求的,公司軟件開發一般都要求在設計和架構上具有極大的彈性,以適應在產品開發的不同階段客戶的不斷變化的需求,甚至在產品發布後也常常如此。這種動態性要求軟件設計必須強健。它應該能夠適應變化並且不會帶來任何不必要的連鎖反應—不應該要求重寫潛在的、不相干的(子)系統。向不具備擴展能力的模塊添加特性和組件是令人沮喪的和難以達到預期目標的。封閉的、無彈性的設計遲早會被變化的壓力所壓垮。設計模式有助於彈性架構的基礎鋪設,而這,是每一個優秀的面向對象設計的共同特點。

  設計模式已經被編目歸類以用於解決從細小問題乃至大規模架構級問題。本文將介紹幾個流行的設計模式,在我自己的項目裡,我發現它們很有用。盡管熟悉面向對象設計的概念有助於理解本文,但我並不假定你具備任何設計模式的預備知識。盡管任何適宜於面向對象開發的程序語言都可以用來闡明模式,但我將只用C#來編寫例子【譯注:但我不是J 我給出了和C#對應的C++的完整示例,以便於熟悉C++的讀者進行比對J】,也借此來展示這門語言的威力。我不會討論任何微軟.NET類庫細節,相反,我將集中於使用C#語言作為設計面向對象軟件的工具。

C#和設計模式

  C#是一個現代的程序語言,它通過提供直接映射面向對象設計概念的句法結構和語義支持來促進面向對象軟件開發。這和C++大不相同,C++同時支持面向過程、面向對象和泛型編程。雖然如此,如果你是一名C++程序員,跟進C#是非常容易的。對於C++程序員來說,這個學習曲線是相當平坦的。即使你以前從未看過任何C#代碼,理解本文示例代碼也不應該有任何問題。事實上,如果你發現C#對設計模式的實現更為清晰,我也不會有任何驚訝,特別是如果你以前使用設計模式編寫過代碼的話。一般討論設計模式的書籍和文章都會詳細地描述模式所要解決的問題和上下文細節,並隨後提供一個規范的解決方案的描述。本文不會那麼嚴謹,我只關注模式本質,並輔以適當的C#示例來加以說明。

讓我們從最簡單的設計模式開始:singleton。

singleton

  任何編寫過MFC應用的開發人員(不管編寫的應用是如何的小)都知道什麼是singleton。singleton是類的唯一實例。使用MFC時,從CWinApp派生的應用類的全局實例就是singleton。當然,在MFC應用中,盡管規定不允許創建應用類的第二個實例,但是並沒有什麼可以阻止你那麼做。【譯注:實際上,不管是VC6.0還是VC7.0Beta2,它們的編譯器都可以一定程度地限制你創建第二個實例。之所以說一定程度上,是因為諸如這種情況編譯器並不幫你檢查—試圖在窗體的某個按鈕事件裡創建應用類的第二個實例】在這種情況下,當你需要某個特定的類表現出singleton行為時,一個更好的替代方案是讓這個類自己負責確保只會被創建一個並且只有一個實例。再回到MFC,我們知道保證應用類實例的唯一性的責任被留給了開發應用的程序員,他(她)們必須小心不要創建應用類的第二個實例。

  現在來看看表1所示的類。singleton的訪問被局限於必須通過靜態方法Instance。多數情況下,singleton應該具有全局可見性,這可通過將其創建方法public來實現。和用全局變量模擬singleton不同,這種模式可以防止創建出多余的實例,同時兼具全局可見性。注意,該類的構造器被置為private,這就意味著沒有任何辦法可以繞過靜態方法Instance來直接創建類的實例。

表1

class Singleton
{
private static Singleton singleton = null;
public static Singleton Instance()
{
if (null == singleton)
singleton = new Singleton();
return singleton;
}
private Singleton()
{
}
}

  singleton模式的作用還不止於此,尤其是可以將其擴展,以創建類的可變數量的實例。假定有一個應用,當需要執行特定任務時就需要調度一個工作者線程。考慮到節約系統資源,我們使用singleton來實現這個線程類。不久,需要singleton線程處理的任務變得密集起來,如果我們決定擴展這個應用,我們可以很方便地增加工作者線程的數量,因為線程的創建和對它們的訪問授權的所有邏輯都被定義在一個類中。

  singleton模式的另外一個優點是singleton的創建可以被延遲到真正需要的時候,正如表1所示。不管是否需要,全局變量一開始就被創建,但這個全局對象並不一定是一直都需要的。C#不支持全局變量,但還是有可能在某個方法的一開始就在堆上創建了一個對象並直到很久以後才使用它。果真如此的話,singleton模式為這種案例提供了一個優雅的解決方案。


 外,作為一個工具,在singleton模式的實現上,C#優於C++,盡管這個優點很微妙,但絕對重要。基於C++的實現需考慮singleton帶來的一些和生命期管理有關的棘手問題,而在C#中則由運行時自動處理。這個優點是有意義的,在singleton模式的C#實現版本中,你只需保證在需要singleton的時候,你擁有一個活的引用即可。

【譯注:以下是singleton模式完整示例

C#示例:
using System;
class Singleton
{
private static Singleton singleton = null;
public static Singleton Instance()
{
if (null == singleton)
singleton = new Singleton();
return singleton;
}
private Singleton()
{
}
}
class Application
{
public static void Main()
{
Singleton s1 = Singleton.Instance();
file://Singleton s2 = new Singleton(); file://錯誤:構造器不可訪問
Singleton s2 = Singleton.Instance();
if (s1.Equals(s2)) // 引用相等
Console.WriteLine("Instances are identical");
}
}

/*以下是程序輸出結果:
Instances are identical
*/

  C++示例:【譯注:譯者在自己的程序實踐中,幾乎從未將類的聲明和實現攪和在一起,此處示例代碼之所以是如此寫法,只是為了便於大家閱讀和比對而已】

#include "stdafx.h";
#include
class Singleton
{
public:
static Singleton* Instance()
{
if (NULL == singleton) singleton = new Singleton();
return singleton;
};
private:
Singleton()
{
};
private:
static Singleton* singleton;
};
Singleton* Singleton::singleton = NULL;
int _tmain(int argc, _TCHAR* argv[])
{
Singleton* sgt1 = Singleton::Instance();
Singleton* sgt2 = Singleton::Instance();
if(sgt1 == sgt2)
cout<<"Instances are identical ";
delete sgt1;//【譯注:這個簡單的例子裡,是不存在內存洩漏或棘手的生命期管理問題的J】
return 0;
}
/*以下是程序輸出結果:
Instances are identical
*/

strategy

  應用常因用戶輸入、運行平台和部署環境等的不同執行的任務亦不相同。以磁盤文

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved