一、 引言
早在2001年,我就著手開發一個asp.net在線消息板應用程序webforums.net。其目的是創建一個基于asp.net的消息板系統,而且該系統可以容易插入到一個現有網站中。構建這樣一個端對端應用程序的特別挑戰之一就是,要為客戶提供一種方式以便能夠把它集成到他們自己的系統中去。例如,一個在線論壇明顯需要使用某種數據存儲來存儲用戶信息、論壇、回寄信息等;但是,最好不要把客戶鎖定到一種特定的數據存儲中。也就是說,你不應該說,"我的應用程序必須使用微軟的sql server 2000";因為這樣的話,使用oracle或access的客戶怎么會使用你的軟件呢?
另一個集成到客戶現有數據中的問題是,所有的在線論壇站點都提供用戶帳戶和一種創建新帳戶的方式。典型情況下,這被建模為一個論壇架構(以一個數據庫中的users表形式存在)。但是,客戶很可能已經有他們自己的擁有成千的用戶帳戶的數據庫表?;蛘撸粋€客戶可能想在一個內部網設置中使用該論壇,并且想使用活動目錄而不是某種數據庫表來認證和存儲用戶信息。因此,當一個論壇軟件系統創建一個users數據庫表并對其客戶說"這就是你存儲用戶的方式"時,那些已經擁有現有基礎結構和用戶數據的客戶很可能會疏遠這樣的軟件。
因此,當你使用一種"僵硬"的api構建一個系統時,會產生特別的挑戰。一種"僵硬"的api不是提供一種方式來定制邏輯而是硬編碼實現細節(例如,你必須使用sql server作為你的后端數據存儲,且在這個數據庫有一個users表,并將在其中存儲所有的用戶信息)。然而,通過使用提供者設計模式,你可以輕易地打破這種"僵硬"性。借助于提供者設計模式,系統架構師只需要定義api,至于編程功能則由系統來提供。對于一個在線論壇應用程序來說,這可能包括一個具有例如authenticate(username,password)和getuserdetails(username)等方法的users類。
提供者模型的優秀在于客戶實現方案可以指定一個系統應該使用的定制類。這種定制類必須實現系統的良好定義的api;但是,它允許無縫地插入任何定制實現。也就是說,一旦定義這個api,系統實現者可以創建一個使用sql server和一個users表的默認的具體實現-大多數客戶可以直接使用之而不必要作任何修改。那些有定制需要的客戶(他們想使用oracle或以另外一些方式存儲用戶數據)可以創建他們自己的類,該類提供必要的功能并且把它們插入到這些客戶的系統中。
其實,提供者設計模式被應用于整個asp.net 2.0實現中。當然,網上也存在一些如何在asp.net 1.x應用程序中使用這一功能的教程。
在本文中,我們將詳細探討提供者模型并分析如何把它應用于asp.net 2.0開發中。
二、 打破"僵硬"的api實現
在我早期的webforums.net開發中,我認識到,這種"僵硬"的api實現將會成為一個問題。我的軟件設計目標之一就是:盡可能靈活且可定制,并且使用戶使用sql server,而且我的用戶數據模型實現應該看起來充其量只是有些限制性。為了克服這些問題,我構建了一個包含下面兩部分的系統:
1. 一組定義了系統的核心功能的抽象基類;
2. 能夠在運行時刻動態地加載一個擴展抽象基類。具體地說,該代碼負責檢查包含一個<configsetting>節(該節中給出要使用的類的完全限定名)的web.config文件。
借助于這一架構,我可以通過一系列抽象基類來定義系統的功能,并使用sql server 2000和users表來提供這些類的具體實現。滿足這一配置的客戶可以只管使用該應用程序,并且一切將工作良好,且不需要他們編寫一行代碼。然而,那些需要定制的開發者們可以通過創建他們自己的派生自適當的抽象基類的類來實現。通過簡單地把該程序集放到應用程序的/bin目錄并更新web.config文件,他們可以讓系統使用這個新類。具體地說,webforums.net發行中帶有一個抽象基類dataprovider,它清楚地列舉出了系統中的所有方法,類似如下:
| public abstract class dataprovider { public abstract bool authenticateuser(string username,string password); public abstract user getuserinfo(string username); ... public static dataprovider instance() { ... } } |
| <webforumssettings> <add key="dataproviderassemblypath" value="path" /> <add key="dataproviderclassname" value="namespace.classname" /> </webforumssettings> |
| if (dataprovider.instance().authenticateuser(username,password)) //用戶被認證 else //用戶名/口令無效! |
三、 提供者模型優點
提供者模型提供許多優點。首先,在代碼和后端實現之間存在清晰的分離。不管認證一個用戶的代碼是針對一個sql server 2000數據庫的users表還是針對于一個活動目錄存儲,從頁面開發者的觀察看來代碼都是相同的:
dataprovider.instance().authenticateuser(username,password);
而且,后端實現變化是透明的。
因為系統架構師被鼓勵創建默認的實現,所以提供者模型提供了兩種世界的最好結合:如果對默認實現已經比較滿意,那么系統會按預期進行工作;對于需要定制系統的用戶來說,他們盡管定制好了而不必干擾現有代碼或編程邏輯。這個設計模式也使得原型化和靈敏開發容易許多。例如,在早期系統使用階段,僅使用默認實現可能更容易。然而,以后你可能需要定制某些方面以便把該工作與你的公司的現有系統集成到一起。這時,你可以通過提供者模型實現需要的定制。這意味著,不需要改變你的早期工作來反映后端實現的變化。
就象許多好的設計模型一樣,提供者模型也提供了開發者之間的職責分離。這樣以來,一部分開發者可以使用他們精通的系統api進行工作,而另一部分開發者可以專注于后端實現和定制任務開發;而且,這兩組人員可以工作在同一個系統上而不會相互干擾。而且,如果他們所使用的系統是一種工業標準(例如asp.net 2.0),那么這兩類任務中的技能都可以被容易地移植到未來的工作中。
四、 asp.net 2.0提供者模型
asp.net 2.0在全部其架構中都利用提供者模型。例如,它的許多子系統-會員,站點導航,個性化等都利用了提供者模型技術。而且,每個子系統都提供一種默認實現,但也能使客戶定制其功能以滿足他們自己的需要。例如,asp.net 2.0的站點導航部分允許一個頁面開發者定義他們網站的可導航的結構。然后,這些數據就可以被各種web控件所使用以便顯示站點地圖、樹狀視圖或菜單-它們能夠高亮站點的導航并且/或者顯示用戶的站點位置。除了與導航相關的web控件外,站點導航api還提供了一組方法用于實現與網站導航信息的交互。
默認地,站點的可導航信息必須以一個正確格式化的xml文件編碼。這種數據存儲方式是,默認站點導航被硬編碼使用。然而,asp.net 2.0的提供者模型可以使你更容易地使用你自己的數據存儲來實現站點導航。例如,在一個我當前開發的工程中,使用的一個數據庫包含站點中的頁面信息以及不同的用戶擁有頁面中什么樣的許可權。不是在一個xml文件中重新定義這些信息并且必須努力保持兩份信息的及時更新;而是,通過利用asp.net 2.0中的站點導航功能,我可以簡單地創建一個提供者類,它能夠直接與數據庫信息工作。一旦創建這個類并且在網站的配置中指定,導航web控件就可以根據存儲在數據庫中的應用程序的定制導航信息進行工作。(注意:在本文成文之時,這個工程使用的仍然是asp.net 1.x;然而,這個例子卻有希望能夠向你展示提供者模型的優點。)
作為個人,我想,提供者模型只是asp.net 2.0提供的最優秀的遷移特征之一。asp.net 2.0提供了很多開發者在1.x版本中必須定制的新特征。如果這些2.0版本的新特征使用過于"僵硬"的實現方式,那么它將阻止基于定制方案的正在使用中的1.x應用程序向它的遷移,因為許多新的asp.net 2.0 web控件都使用了這些新的子系統。然而,有了提供者模型后,我們就可以把我們的1.x應用程序升級到2.0版本并且創建一個提供者以便使2.0版本的新的子系統與我們的定制方案集成到一起。這意味著,當遷移到2.0版本時,我們可以使用新的web控件并且使它們通過提供者模型而自然地使用我們的現有系統。
五、 補充信息
隨著提供者模型成為asp.net 2.0中的一個重要組成部分,微軟出版了很多關于這個主題的文章。如果你想了解更多這方面的信息,那么我鼓勵你閱讀一下rob howard的兩篇文章:
· 《提供者模型設計模式與規范》;
· 《asp.net 1.x提供者模型》。
其中,第二篇文章分析了如何把提供者模型應用于你的asp.net 1.x應用程序。還有兩篇文章討論了asp.net 2.0的站點導航子系統中的提供者用法:
· 《理解和擴展asp.net 2.0中的站點導航系統》,作者david gristwood;
· 《定制asp.net 2.0中的提供者》,作者morgan skinner。
注意,微軟還發行了另外一個提供者開發工具包,它也用于創建asp.net 2.0提供者。而且,還有一篇不錯的文章《asp.net 2.0提供者模型》可供你參考。
六、 結論
當創建具有各種要求的大量客戶所使用的系統時,一種"僵硬"的api實現可能會"嚇壞"了開發者;這種"僵硬"的實現往往會強迫客戶同意且被鎖定于系統架構師的"視野"之內。而一般地,公司往往更對能夠與他們的現有方案協同工作的應用程序和框架感興趣而不是強迫他們的方案服從供應商提供的系統。
提供者模型提供了一種打破這種"僵硬"的實現問題的方法。借助于提供者模型,系統就能夠靈活地使用擴展特定基類的任何類。這樣以來,客戶可以創建他們自己的包括他們的定制邏輯和業務規則的派生類。而且,這些新類可以無縫地插接到系統中,而不必干擾應用程序中的現有代碼或任何自創建以來的新的定制代碼。
總之,提供者模型在asp.net 2.0中得到普通使用;而且這些概念也可以應用于asp.net 1.x應用程序中。
新聞熱點
疑難解答
圖片精選