1         什麼是設計模式

設計模式是對在軟體設計過程中重複出現的問題提出了一種比較好的解決方案。正如一位專家所說:設計模式是對程式設計人員經常遇到的設計問題的可再現的解決方案(The Smalltalk Companion)。GOF設計模式通常被認為是其他設計模式的基礎,隨著業務複雜度的增大,會不斷湧現新的設計模式,而這些新的設計模式一般會以GOF模式理論為參照。

2         為什麼要學習設計模式

從個人職業規劃來考慮。一位軟體開發工程師隨著編碼量的增加,開發經驗的增加,軟體理論理解的加深,會不由自主地想一些方法或者捷徑,來提高自己的生產率,而不是面對重複的問題做相同的工作,當你有這種想法的時候,就需要開始學習設計模式,設計模式會給你一些比較好的解決方案,不但解決了問題也提升了自己的能力,同時也是邁向軟體設計師和架構師的過度階段。

從軟體架構的角度來考慮。經濟的快速發展造就了業務越來越複雜,那麼如何使軟體適應這種複雜的業務變化,在軟體設計和架構時,適當地使用設計模式可以解決此問題,也要注意不要過度使用設計模式,否則會使系統變的更加複雜。設計模式也是程式碼重構的依據和工具,建議在程式碼的重構時,儘量融入設計模式。

3         設計模式原則

使用設計模式的根本原因是適用變化,提高程式碼複用率,使軟體更具有可維護性和可擴充套件性。需要遵循以下幾個原則:單一職責原色、開放封閉原則(Open Closed Principal)、依賴倒置原則、里氏代換原則。

3.1單一職責原則

就一個類而言,應該只有一個引起他變化的原因。如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會消弱或者抑制這個類完成其他職責的能力。這種耦合會導致脆弱的設計,當變化發生時,設計會遭受到意想不到的破會。

3.2開放封閉原則

       軟體實體(類、模組、函式等)應該可以擴充套件,但不可以修改。也就是說對擴充套件是開放的,對修改是封閉的。一般來說,面對需求,對程式的改動是通過新增新程式碼進行的,而不是更改現有程式碼。

3.3依賴倒置原則

       抽象不應該以來細節,細節應該依賴抽象,也就是提倡的“面對介面程式設計,而不是面對實現程式設計”。也可以這樣理解:高層模組不應該依賴底層模組,兩個都應該抽象;抽象不應該依賴細節,細節應該依賴抽象。

3.4里氏代換原則

       子類必須能夠替換掉他們的父型別。也就是說,在軟體開發過程中,子類替換掉父類,程式的功能行為沒有變化。只有當子類可以替換掉父類,軟體單位的功能不受到影響時,父類才能真正被複用,而子類也可以在父類的基礎上增加新的行為。

4         設計模式四個基本要素

設計模式使人們可以更加簡單方便地複用成功的設計和體系結構,將已證實的技術表述成設計模式也會使新加入的系統開發者更加容易理解其設計思路。設計模式的基本要素包括模式名稱、問題、解決方案和效果。

4.1模式名稱

       一個助記名稱,用來描述設計模式、解決方案和效果。設計模式允許在較高的抽象層次上進行設計。基於一個模式詞彙表,開發團隊之間可以討論模式並在編寫文件時使用它們。模式名稱可以幫助我們思考,便於團隊成員交流設計思想及設計結果。找到合適的模式名稱也是設計模式編目工作的難點之一。

 4.2問題

問題主要描述在何時使用設計模式。它解釋了設計問題和問題存在的前因後果、特定的設計問題和怎樣用物件表示演算法等。通常情況下,模式必須滿足的一系列先決條件是問題。

 4.3解決方案

       解決方案描述了設計的組成成分、它們之間的相互關係及各自的職責和協作方式。因為模式就像一個模板,可應用於多種不同場合,所以解決方案並不描述一個特定具體的設計或實現,而是提供設計問題的抽象描述和怎樣用一個具有一般意義的元素組合(類或物件組合)來解決這個問題。

4.4效果

描述了模式應用的效果及使用模式權衡的問題。儘管描述設計決策時,並不是總提到模式效果,但它們對於評價設計選擇和理解使用模式的代價及優勢具有重要意義。軟體效果大多關注對時間和空間的衡量,它們也表述了語言和實現問題。因為複用是物件導向設計的要素之一,所以模式效果包括它對系統靈活性、擴充性或可移植性的影響,顯式地列出這些效果對理解和評價這些模式很有幫助。

5         設計模式分類

設計模式主要分為建立性模式( Creational Patterns)、結構性模式(Structural Patterns)、行為性模式(Behavioral Patterns)。

5.1建立性模式( Creational Patterns

5.1.1 Net設計模式例項之簡單工廠模式(Simple Factory Pattern)

簡單工廠模式(Simple Factory Pattern)的優點是,工廠類中包含了必要的邏輯判斷,根據客戶端的選擇條件動態例項化相關的類,對於客戶端來說,去除了與具體產品的依賴

5.1.2 Net設計模式例項之抽象工廠模式(Abstract Factory Pattern)

抽象工廠模式(Abstract Factory Pattern),提供一個建立一系列相關或者相互依賴物件的介面,而無需制定他們的具體類。抽象工廠模式的典型應用就是,使用抽象工廠+反射+配置檔案實現資料訪問層程式

5.1.3 Net設計模式例項之單例模式( Singleton Pattern)

單例模式(Singleton Pattern,保證一個類只有一個例項,並提供一個訪問它的全域性訪問點。單例模式因為Singleton封裝它的唯一例項,它就可以嚴格地控制客戶怎樣訪問它以及何時訪問它。

5.1.4 Net設計模式例項之建造者模式(Builder Pattern)

建造者模式(Builder Pattern),將一個複雜物件的構建與它的表示分離,使的同樣的構建過程可以建立不同的表示。建造者模式是在當建立複雜物件的演算法應該獨立於該物件的組成部分以及他們的裝配方式時適用的模式

5.1.5 Net設計模式例項之原型模式( Prototype Pattern)

原型模式(Prototype Pattern):用原型例項指定建立物件的種類,並通過拷貝這些原型建立新的物件。Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype

淺複製與深複製區別:

淺複製,被複制的所有變數都還有與原來物件相同的值,而所有的對其他物件的引用都仍然指向原來的物件。深複製,把引用物件的變數指向複製過的新物件,而不是原有的被引用的物件。

Net名稱空間System提供了一個IConeable介面,此介面只有一個方法Clone(),只需要實現這個介面就可以實現原型模式(Prototype Pattern)了

5.2結構性模式(Structural Patterns

5.2.1 Net設計模式例項之介面卡模式(Adapter Pattern

介面卡模式,將一個類裝換成客戶期望的另外一個介面。Adapter模式統一了不相容物件的介面,使的原本由於介面不相容而不能工作的那些類可以一起工作。

5.2.2 Net設計模式例項之橋接模式( Bridge Pattern)

橋接模式(Bridge Pattern),將抽象部分與它的實現部分分離,使的抽象和實現都可以獨立地變化。Decouple an abstraction from its implementation so that the two can vary independently.

什麼是聚合/組合:

聚合(Aggregation),當物件A被加入到物件B中,成為物件B的組成部分時,物件B和物件A之間為聚合關係。聚合是關聯關係的一種,是較強的關聯關係,強調的是整體與部分之間的關係。

5.2.3Net設計模式例項之組合模式(Composite Pattern

組合模式,將物件組合成樹形結構以表示部分整體的層次結構,組合模式使得使用者對單個物件和組合物件的使用具有一致性。解決整合與部分可以被一致對待問題。

5.2.4 Net設計模式例項之裝飾者模式(Decorator Pattern

裝飾模式,給一個物件動態新增額外職責,這些職責需要由使用者決定加入的方式和時機。裝飾模式提供了即插即用的方式,在執行期間決定何時增加何種功能。就增加功能來說,裝飾模式比生成子類更加靈活。

5.2.5 Net設計模式例項之外觀模式(Façade Pattern

外觀模式,為子系統的一組介面提供一個統一的介面,此模式定義了一個高層介面,這一個高層介面使的子系統更加容易使用。外觀模式可以解決層結構分離、降低系統耦合度和為新舊系統互動提供介面功能。

5.2.6 Net設計模式例項之享元模式( Flyweight Pattern)

享元模式(Flyweight Pattern,運用共享技術有效支援大量細粒度的物件。Use sharing to support large numbers of fine-grained objects efficiently. 享元模式可以避免大量非常相似類的開銷。在程式設計中有時需要生成大量細粒度的類例項來表示資料。如果發現這些例項除了幾個引數外基本傷都是相同的,有時就能夠受大幅度第減少需要例項化的類的數量。如果能把這些引數移到類例項外面,在方法呼叫時將他們傳遞進來,就可以通過共享大幅度地減少單個例項的數目。

享元物件的內部狀態與外部狀態:

內部狀態,在享元物件的內部並且不會隨環境改變而改變的共享部分。

外部狀態,隨環境改變而改變的,不可以共享的狀態。

5.2.7 Net設計模式例項之代理模式(Proxy Pattern

代理模式(Proxy Pattern)對其他物件提供一種代理以控制對這個物件的訪問。

5.3行為性模式(Behavioral Patterns

Net設計模式例項之職責鏈模式(Chain Of Responsibility

後期補此節

5.3.1Net設計模式例項之命令模式(Command Pattern)

命令模式(Command Pattern)將請求封裝為一個物件,從而使你用不同的請求對客戶進行引數化,對請求排隊或紀錄請求日誌,以及支援可撤銷的操作。當需要有撤銷或者恢復操作時,可以考慮使用命令模式.

5.3.2Net設計模式例項之直譯器模式(Interpreter Pattern

直譯器模式(Interpreter Pattern),給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。當有一個語言需要解釋執行,並且你可將該語言中的句子表示為一個抽象的語法樹時,可以考慮使用直譯器模式。

5.3.3 Net設計模式例項之迭代器模式(Iterator Pattern

迭代器模式(Iterator Pattern),提供一種方法順序訪問一個聚合物件中元素,而不暴露改集合物件的內部表示。迭代器模式就是分離了集合對想的遍歷行為,抽象出一個迭代器類來負責,這樣即可以不暴露集合的內部機構,又可讓外部程式碼透明地訪問集合內部的資料.

5.3.4 Net設計模式例項之中介者模式(Mediator Pattern

中介者模式(Mediator Pattern),定義一箇中介物件來封裝系列物件之間的互動。中介者使各個物件不需要顯示地相互引用,從而使其耦合性鬆散,而且可以獨立地改變他們之間的互動。中介者模式一般應用於一組物件以定義良好但是複雜的方法進行通訊的場合,以及想定製一個分佈在多個類中的行為,而不想生成太多的子類的場合.

5.3.5 Net設計模式例項之備忘錄模式(Memento Pattern)

備忘錄模式(Memento Pattern),在不破壞封裝的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可以就該物件恢復到原先儲存的狀態。

當系統功能比較複雜,而且需要記錄歷史屬性以便當需要時做恢復動作。Originator可以根據儲存的Memento資訊還原到前一狀態。

5.3.6Net設計模式例項之觀察者模式(Observer Pattern

觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件,這個主題物件在狀態發生變化的時,會通知所有觀察者物件,使他們能夠自動更新自己。解決的是當一個物件的改變需要同時改變其他物件的時候問題。最後以股票例項進一步闡述了觀察者模式。 

5.3.7Net設計模式例項之狀態模式(State Pattern)

狀態模式(State Pattern),當一個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。當一個物件行為取決於它的狀態,並且它必須在執行時刻根據狀態改變它的行為時,就可以考慮使用狀態模式了.

Net設計模式例項之策略模式(Strategy Pattern

後期補此節

5.3.8Net設計模式例項之模板方法模式(Template Mothed Pattern)

模板方法模式(Template Method Pattern),定義一個操作中的演算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可以重定義演算法的某些特定步驟。模板方法模式把不變行為搬移到超類,從而去除子類中的重複程式碼,實際上模板方法模式就是提供了一個程式碼複用平臺。

      要完成在某一細節上層次一致的一個過程或一系列步驟,但個別步驟在更詳細的層次上實現不同時,可以使用模版方法模式解決問題。

 

5.3.9Net設計模式例項之訪問者模式(Visitor Pattern

訪問者模式表示一個作用於某物件結構中的個元素操作。它使你可以在不改變各元素類的前提下定義作用於這些元素的新操作. 訪問者模式的目的是要把處理從資料結構分離出來

6         設計模式總結

Net設計模式系列文章介紹了GOF 23個模式,從模式的設計理念、設計框架、框架的程式碼介紹了設計模式,並且每個模式配有模式例項,UML設計及其C#程式碼。使用的設計工具是EAEnterprise Architect.主要參考的書籍有《Head First 設計模式》《大話設計模式》《Net與設計模式》《C# 3.0 Design Pattern》及其國外一些文章的例項,在此對這些書的作者感謝,在閱讀此係列文章之前,建議大家先閱讀《UML建模系列文章總結

至此,Net設計模式例項系列文章已經寫完,由於個人能力有限,不免有些問題闡述的不清楚或者不是非常正確,望高手指點。再此感謝