重温经典之《企业应用架构模式》——.NET中的架构模式运用 (Base Patterns 1)
在這本書的最后一章,Martin Fowler放了一大堆各種各樣的模式,稱之為“基本模式(Base Patterns)”,這些模式大多比較簡單,專注于解決企業應用中的某個細節問題,可以說不大重要,但真的用到時候有確實那么有用。
因為模式簡單,所以模式本身就不用花太多文字解釋,我們的重點應該放在體會各種模式的異同。甚至有的模式,早已經成為了我們熟知的一種再平常不過的功能,而不需要再去認為其實一種“模式”了,從中,我著實體會到了模式的發展。
Gateway(入口)
每天的編程我們都會面對大量的API,在處處OO的今天直接面向API編程顯然不是一個好的選擇,于是我們就引入Gateway,其實很簡單,就是把現有的API先封裝一下,然后抽象出方便系統調用的接口,再使用。
反正,程序需要什么,我們就為Gateway類定義什么樣的接口,至于如何實現,就完全不用管了。
如果你接觸過GOF的面向對象設計模式,應該會發現這和另外三種模式很相像,它們分別是Fa?ade, Adapter, Mediator,書中著重介紹了這幾種的區別。我重點強調的是,這四種模式,都至少提供了對一個現有對象的再次封裝,而區別微妙的體現在封裝的目的上,而這種微妙的區別,大家得細細體會。
Gateway是在已經有了現成的服務類情況下,為了簡化客戶程序的編寫,將服務類的提供的API接口進一步簡化,一方面簡化調用,另一方面方便測試;
這和Adapter非常相像,但是Adapter所做的工作僅僅是重新封裝一個服務類使之能與另一個調用它的客戶程序匹配,而Gateway并不包含客戶類,因此從這個意義上來說,Gateway = 定義新的客戶代碼接口 + 進行Adapter
最后其實不管什么模式,都可以算作Fa?ade,但是Fa?ade著重在服務代碼編寫的時候考慮,重點在隱藏不公開的成員,暴露程序功能
而Mediator倒是比較清楚,Mediator模式中服務類和客戶類都會調用新定義的中介類,這是和其他幾個模式顯然不同的地方。
?
???????? 要是你堅持看完了以上這些異同,估計你已經快暈過去了。其實說實話,在.NET+C#的平臺這幾種所謂的模式表現在代碼上很可能是一模一樣的,之所以要分成這么多種模式,完全是從模式的思想上來看的。
???????? 雖然學院派了一點,但我還是認為理解這幾種模式對從更高層次上理解面向對象編程編程有很大的幫助。下面看看它們.NET框架里的應用。
?
???????? System.IO.File類,負責磁盤文件的創建,刪除等等工作,在Windows平臺下,這些操作就是調用了Windows API的幾個文件處理函數??傮w上看來,.NET框架是利用Gateway模式封裝了幾個API函數,并作為File類中的成員公開出來。
???????? 使用Reflactor工具我們可以大概的看看.NET的File類是如何工作的,這里就以CreateFile方法為例,經過一次次的轉到定義(提供的重載可真是多),最終我們看到這樣一個復雜的方法(FileStream.Init),定義如下
???????? internal unsafe void Init(string path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, Win32Native.SECURITY_ATTRIBUTES secAttrs, string msgPath, bool bFromProxy)
這雖然已經是一個unsafe方法了,但依然是一個.NET下的類,再繼續看下去,所有方法最終都會調用這樣一個類:
internal static class Win32Native{ … } Win32Native這個類負責直接封裝了所有的WindowsAPI,按照原來的樣子提供了WindowsAPI的封裝,其中用于創建文件的方法名叫Win32Native.SateCreateFile 真的有好多層封裝,我們來看看一個簡單的File.Create方法到底進行了多少調用(跳過方法重載): ??????????????????? File.Create -> ?FileStream.Init -> Win32Native.SafeCreateFile -> WindowsAPI 也許你平時知道.NET很多功能都是直接調用WindowsAPI,但是你可能沒有想到在WindowsAPI上還有這么多層封裝吧。為什么要有這么多層封裝呢? ?從Gateway模式的角度來看,每一層封裝,都是對上一層簡化,每一層都是上一層的Gateway。
Win32Native類,提供了dll文件導入,API函數映射到.NET函數功能;
映射出來的函數非常多,那就公開一個文件處理方面的封裝吧,于是有了FileStream類,我想這叫做Fa?ade可能更好一些;
我們可以看到Init函數非常復雜,到這為止僅僅只是簡單的導出WindowsAPI的函數,使用起來仍然相當不方便,于是我們便加上一個Gateway,這個Gateway封裝了所有unsafe的代碼,處理了很多該處理的異常,最后甚至提供了一個最簡單的重載File.Create(string fileName);
到此為止,創建文件這個功能封裝完畢了,和使用WindownsAPI創建文件比起來,使用一個簡單的File.Create來創建文件真的很完美。
Mapper(映射器)
Gateway模式中對象調用是單向的,Gateway所起的作用僅僅是對低層函數或者類的封裝,而Mapper希望完成的事情遠不止這些。Mapper模式的重點在于關注映射兩種不同機制的系統,他希望通過一個中間的Mapper,完全隔離兩個系統,是兩者完全不互相依賴。
聽得最多的,也許就是最有爭議的ORM(Object Relational Mapping)。
ORM的話題總是說不完的,簡單面向對象系統和關系數據庫系統是兩種完全不同的系統,但是我們又必須使用關系數據庫系統存儲數據,因此我們需要一種程序來進行面向對象數據和關系數據庫中存儲的數據之間的轉換。
Mapper的作用就是處理這種轉換,這個概念很早就被提出來,但是很模糊,因為他并沒有說清楚這個“轉換”到底如何設計,好多年前Martin Fowler就提出了Mapper,甚至提出了Data Mapper的簡單實現,但是直到今天,在.NET框架下還是沒有看到一個真正完美的ORM框架。
我們要理解的,是映射器這種思想,設計一種類,直接在兩種不同的機制間進行轉換,讓雙方都滿意。這很像Adapter,其實我也不能很清楚的說出Adapter和Mapper的區別,可能他們的差別在于粒度上吧,Adapter在于兩種類之間的接口轉換,而Mapper不只是接口間的轉換,他更在意兩種完全不同實現機制之間的相互轉換,這種轉換的技術含量要高得多。
?
在.NET平臺下,嚴格意義上說.ORM框架應該只有剛剛推出的ADO.net Entity Framework,這套框架就著重在于對面向對象設計中的各種繼承組合關系到關系數據庫的映射工作,當然它畢竟是剛推出的工具,我也沒有多少實際使用經驗,到底如何也不好說。
其他的ORM工具從開源NHibernate到NBear等等可以說多如牛毛,而MS官方的除了之前的DLINQ之外,其實以前的強類型Dataset都可以算作簡單的ORM,至少是具有ORM概念的東西。
總的說來,ORM概念已經熱了好幾年了,但是依然還是很不成熟。
和ORM一樣,我認為直到今天Mapper模式也尚未走向成熟,也許,隨意的希望隔離兩個本來就相關的子系統這種行為本身就有些不切實際。
Layer Supertype
???????? 一句話就可以說的非常清楚:如果多個類有同樣的成員,那么建立一個基類,讓所有的類繼承這個基類。
???????? 我沒什么好說的了,老外真的很喜歡總結,連這都能算作一種模式。
???????? 如果這真的算一種模式的話,在.NET框架中,這樣的運用就是數不勝數了,幾乎絕大多數繼承關系的都可以算作這種模式,比如WinForm中TextBox和Button同樣繼承于Control類。
Separated Interface
并非每一種面向對象編程語言都有接口(Interface)這個概念的,但在像C#或者Java這樣在語言級別提供了接口功能的語言中,接口的使用已經是司空見慣了。
要說明的是,實現Separated Interface并非一定要使用接口這東西,用抽象類也是可以很好的實現接口的。
為什么要用接口,大聲喊出一句話,把聲明和實現分開!
這里涉及到一些基礎的東西了,有了抽象類,為什么還要有接口呢?
一個原因是類的繼承關系僅僅只是一個面向對象系統中縱向的關系,而同一層次的類之間的關系則無法使用繼承關系描述,除非,使用C++的多繼承。
實踐證明,多繼承帶來的問題遠大于好處,因此便有了更注重功能定義的接口,這個概念。接口更重在描述體現類本身的功能,接口并不關心這個類“是”什么,他只關心這個類“能做什么”。
從這個意義上來說,接口定義了類之間橫向的功能關系。這是另一種結構上優化。
?
縱向繼承關系
在繼承的基礎上加上橫向實現關系
?
IWork2也許并沒有定義在ClassRoot中,但是因為接口的存在,本來沒有關系的ClassB和Class3被建立了關系,這就是橫向的實現關系。
更加重要的是,我們可以把IWork1和IWork2的實現放在其他的程序集或者包中,在我們發布的版本中,只需要指定我們所依賴的接口就足夠了。這大大降低了各個程序集之間的耦合度。
分離接口在.NET框架中的運用也是遍地都是,也許你已經根本不認為只是一種模式了,而只是非常平常的使用它了。這便是模式的最高境界,也可見這種分離接口模式的成熟。
舉個最典型例子,在定義WCF服務的過程中有一個步驟是定義WCF的ServiceContract, ServiceContract實際上就是一系列接口。在創建一個WCF服務時,通常會將所有的服務代碼抽象成這樣的接口,客戶端只需獲得這個接口,就能夠進行遠程調用服務器以使用。關于WCF的詳細信息,可以參考MSDN,或相關資料。
轉載于:https://www.cnblogs.com/yayx/archive/2008/09/02/1285336.html
總結
以上是生活随笔為你收集整理的重温经典之《企业应用架构模式》——.NET中的架构模式运用 (Base Patterns 1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转)致李开复博士的一封信
- 下一篇: SQL Cache Invalidati