C#面向對象設計模式縱橫談 第25講:設計模式總結

>>>  技術話題—商業文明的嶄新時代  >>> 簡體     傳統

2006.10.23 李建忠

創建型模式

Singleton模式解決的是實體對象個數的問題。除了Singleton之外,其他創建型模式解決的都是new所帶來的耦合關系。

Factory Method,Abstract Factory,Builder都需要一個額外的工廠類來負責實例化“易變對象”,而Prototype則是通過原型(一個特殊的工廠類)來克隆“易變對象”。

如果遇到“易變類”,起初的設計通常從Factory Method開始,當遇到更多的復雜變化時,再考慮重構為其他三種工廠模式(Abstract Factory,Builder,Prototype)。

 

結構型模式

Adapter模式注重轉換接口,將不吻合的接口適配對接(適合于舊系統)

Bridge模式注重分離接口與其實現,支持多維度變化

Composite模式注重統一接口,將“一對多”的關系轉化為“一對一”的關系

Decorator模式注重穩定接口,在此前提下為對象擴展功能

Facade模式注重簡化接口,簡化組件系統與外部客戶程序的依賴關系

Flyweight模式注重保留接口,在內部使用共享技術對對象存儲進行優化

Proxy模式注重假借接口,增加間接層來實現靈活控制

 

行為型模式

Template Method模式封裝算法結構,支持算法子步驟變化

Strategy模式注重封裝算法,支持算法的變化

State模式注重封裝與狀態相關的行為,支持狀態的變化

Memento模式注重封裝對象狀態變化,支持狀態保存/恢復

Mediator模式注重封裝對象間的交互,支持對象交互的變化

Chain Of Responsibility模式注重封裝對象責任,支持責任的變化

Command模式注重將請求封裝為對象,支持請求的變化

Iterator模式注重封裝集合對象內部結構,支持集合的變化

Interpreter模式注重封裝特定領域變化,支持領域問題的頻繁變化

Observer模式注重封裝對象通知,支持通信對象的變化

Visitor模式注重封裝對象操作變化,支持在運行時為類層次結構動態添加新的操作

 

模式之間的關系圖

image

 

例說模式綜合應用

我們以做一個文件分割器為例

image

剛開始做的時候我們并不知道應該用什么模式。

瀏覽

image

分割,把文件作二進制處理,拿到文件長度,和分割數量,然后順序讀取文件進行處理。

image

image

image

從設計層面來想,這樣的設計是很粗糙的。能正常工作并不意味著能很好的工作。

假如現在提出幾個需求:

1.程序沒有通知,如果分割一個大文件,用戶等了很久都不知道你在干什么,因此應該提供一個進度條。

2.發郵件的時候對文件分割器的需求比較大,我們希望在發郵件的時候監測到郵件太大就自動分割文件,分割同時發出一個協議文件,描述了分割的步驟和順序,然后客戶端拿到分割后的文件,再根據協議合并文件。這樣文件分割器就應該適用于可復用的組件。

3.文件太大分割器會導致內存暴漲。問題在于代碼中的

image

例如我們要把1G的文件分割成4份,這意味著一次就需要從硬盤上讀200多M,這樣對內存的需求就會暴漲。因此程序的算法還需要改進。

 

開始重構

第一步首先要分離耦合,把表現層與業務層分離。

image

image

整個算法放到Split函數里面。接下來表現層只需要實例化一個分割算法類即可。

image

這樣界面和類庫的代碼就順利解耦了。這樣的話我們就可以把分割類庫作為獨立的dll被Outlook等應用程序調用了。

 

然后我們考慮,MyFileSplitter類庫很可能會改變,特別是Split算法的改變頻率可能更高。但是現在我們的表現層是依賴于邏輯層的,因此我們想到要在中間搭一層接口。這就要用到創建型模式。

image

image

image

表現層可以用工廠模式創建ISplitter的實例,這里我們直接使用反射來創建實例。

image

這樣表現層就不與業務邏輯層直接產生依賴了。

然后我們考慮進度條,這涉及到對象與對象的通知關系,即觀察者模式。C#的委托事件機制其實就是這個模式的運用。

image

在ISplit接口里添加SplitProgressEventHandler委托事件。之所以添加在接口里是因為接口十分穩定。

image

Split分割文件的實現方法中添加觸發進度條事件。

image

image

表現層,根據接收到的通知,更新進度條。

image

然后我們再解決內存暴漲的問題,我們不要一口氣讀太多的文件內容,我們可以一次讀1M,讀到規定數量后才寫到一個小文件中。另外,我們還可以使用多線程并行地去讀一個大文件,這都是屬于算法的更改,因此我們可以想到把Split方法劃分出去,用Strategy模式解耦。

另外我們還需要寫一個文件合并器,這些都可能用到其他的很多設計模式。例如我們還可能需要支持網絡上文件的分割,斷點續傳技術等等,這些都是可能的變化點,需要我們考慮。

 

設計模式應用總結

設計模式建立在對系統變化點的基礎上進行,哪里有變化點,哪里應用設計模式。

設計模式應該以演化的方式來獲得,系統的變化點往往是經過不斷演化才能準確定位。

不能為了模式而模式,設計模式是一種軟件設計的軟力量,而非規范標準。不應夸大設計模式的作用。

2010.11.1


MSDN 網絡廣播 李建忠 2013-08-22 08:55:19

[新一篇] C#面向對象設計模式縱橫談 第24講:Visitor 訪問者模式

[舊一篇] Silverlight4 RIA應用開發
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表