全部的優秀程序員都會盡本身的最大努力去使本身所寫的程序具備更好的可重用性,由於它可讓你快速地寫出更加健壯和可升級性的程序。
有兩種使代碼重用的選擇:
1.白盒:最簡單的一種,就是把你的程序片拷貝到另外一個文件中。
2.黑盒:它包括把編譯過的程序片鏈接起來。所以客戶端能夠調用的編譯過的黑盒類庫就叫做組件。
.Net中也一樣爲開發者提供了相似於COM的創建和展開組件的方法。開發人員很容易地被這兩種以組件爲基礎的開發模型所迷惑,因此,讓咱們來看一看這些不一樣的開發方法,以使咱們消除疑惑。
COM的產生
在之前程序設計過程當中,程序員把它們的函數庫放在一個叫作目標(Object)文件的單獨文件中,在這些文件中,包含了編譯過的代碼。當程序員要使用一個特別的目標文件的時候,他們把客戶程序編譯成機器代碼,而後依靠動態連接的手段把客戶程序聯接到目標文件上,最後變成一個單一的可執行文件。這種做法的惟一的好處在於它節省了編譯函數庫的時間。可是它有許多的缺點,好比因爲在每一個單獨的可執行文件中都有一個程序庫包括在裏面,浪費了許多存儲空間;對應用程序的維護也是很是困難的,若是在函數庫中發現了一個bug,整個可執行文件都要被從新編譯和分發。
還有不僅一個的嚴重的限制在裏頭,一個客戶應用程序必需要和用同一種語言編制的函數庫在一塊兒才能使用。好比說,一個用QuickBasic寫的客戶應用程序就不能引用一個用C++寫的函數庫。
所以,微軟公司出品了COM,COM僅僅只是一個規範。無論組件用什麼語言寫成,只要符合這個COM規範,就能被用任何一種語言寫成的客戶程序調用。此外,程序員沒必要再擔憂要去創建一個單一的可執行文件,由於組件是以GUID(Global Unique Identifier全球惟一標識符)來標識的。GUID是一個128位的號碼,和一些相關的信息一塊兒被放在系統的註冊表中,用來惟一標識組件。客戶應用程序只在運行期間才動態地創建一個組件的實例,並使用這個組件的功能,所以,只須要一個函數庫的拷貝。它的缺點就是你們經常提到?quot;DLL地獄"。這個問題在一個DLL要被一個新版本的DLL所取代時引起。開發者不得不經過關閉全部的客戶應用程序的方法(若是不行,還要關閉WWW服務)來達到清除所用對這個組件的引用的目的。有時全部的方法都還起不了做用,那你只好從新啓動服務器後才能替換掉老的DLL。
COM+
爲了讓企業級的應用程序能使用上COM,它必須要有如下的特定的能力。
· 驗證能力
· 對象池(Object Pooling)
· 事務處理
· 支持分佈式架構
爲了使開發者沒必要去爲他們的組件添加這些能力,微軟公司出品了DCOM(Distributed COM分佈式COM)和MTS(Microsoft Transaction Server微軟事務服務器)。使用這兩種技術,開發者就能夠把精力用在他們的商業邏輯上,而沒必要放在後臺的他們的組件上。
DCOM是一個用於分佈式的組件之間的通信的RPC(Remote Procedure Call)協議。客戶端向一個本地機的代理類發送請求,而後由代理類將這個請求隱含地給安裝在遠程機器上的"根"類,而後執行結果原路送回給代理類,最後代理類把它們回送給客戶端。所以,客戶程序的位置徹底與組件的位置無關。DCOM的缺點在於,因爲DCOM使用的是一個獨立的硬件端口,而不是HTTP協議的80端口,因此在組件間通信的過程當中,必須保證這個端口是開着的。這是一個嚴重的安全問題。因此DCOM不可以輕易地穿越防火牆。
爲了使用MTS,程序員在它們的組件裏放置特別的MTS鉤子,編譯後把他們放在MTS包中。把有關係的組件放在一個單一的包中有它本身的好處。當客戶請求一個包中的一個組件的一個實例的時候,MTS確保爲這個包創建一個新的專門的線程,一個新的組件實例被創建在這個線程上並被應用事務服務。至於對象池服務和安全服務是否要被創建,那就要看開發者的請求了。
MTS容許相關的做業單元被看成一個事務來對待,這意味着若是全部的做業單元被成功地完成,整個事務就被看成成功地完成,反之若是有一個單元未成功完成,整個事務將被從新輪迴。
在客戶請求對象和釋放對象後,MTS仍保存着這個對象,因此當另外一個客戶請求同一個組件的時候,MTS就將保存着的對象交給它。經過這種方式,MTS減小了在服務器源實例化的次數。
MTS容許開發者用安全措施來組裝他們的組件,以使其具備識別請求它的服務的客戶的能力。這可以確保未經受權的客戶不可以使用組件的功能。
MTS以COM+的名義被完整地整合到了微軟公司的Windows 2000操做系統中,可是COM+不只僅只有MTS,它還包括一些其它的服務。MSMQ(Microsoft Message Queue Server),一個與MTS一同發佈的服務,也被以COM+的名義整合到了Windows 2000中。MSMQ容許服務器端和客戶端進行同步的通信。事件服務(Event Service)也被加了進來,它使服務器可以與客戶端同步地交流事件的發生。負載平衡服務(Load Balancing)自動地實例化機器上的具備最多資源的服務器上的請求對象。
.NET
.Net提供了一種全新的創建和展開組件的方法。它就是大名鼎鼎的Assemblies。使用COM,開發者必須要在服務器上註冊組件,這也就是說,系統註冊表中的組件的信息必須被更新。這樣作的目的是保證組件的中心位置,以使COM+可以找到合適的組件。使用.Net的Assemblies,裝配(Assembly)文件把全部須要的元數據(meta data)都壓入一個叫Manifests(名單)的一個特殊的段中。在.Net中,要使assembly對用戶有效,只要簡單地把他們放在一個目錄中就好了。當客戶程序請求一個特別的組件的實例的時候,.Net運行期(runtime)在同一個目錄搜尋assembly,在找到後,分析其中的manifest,以取得這個組件所提供的類的信息。因爲組件的信息是放在manifest裏的,因此開發者就沒有必要把組件註冊到服務器上,所以,就能夠容許幾個相同的組件安全地共存在一個相同的機器上了。
創建一個.Net assembly並不像創建一個VB6組件,惟一讓開發者操心的就是商業邏輯,全部的後臺代碼所有由.Net運行期產生,並且因爲.NET運行期具備碎片收集器的功能,組件沒必要擔憂它的引用數目(在COM中是靠Iunknown的幫助)。簡單地說,在.NET中創建一個assembly比創建一個VB6 COM要簡單地多。
純的.NET assemblies不可以在COM+服務下注冊,由於它們是和COM不一樣的二進制標準。面對.NET,assemblies的前景相對於COM來講是"高級的COM"。可是因爲當前架構於COM+上的應用程序的可靠性,COM還會持續一段時間。這也許就是微軟公司向開發者同時提供開發.NET assemblies和COM的工具的緣由吧。
類型庫引入器(Type Library Importer (TLBIMP.exe))工具能夠把COM組件封裝成.NET,以使之前的東西能夠在.NET應用程序中繼續使用。
類型庫導出器(Type Library Exporter (TLBEXP.exe))工具將.NET組件封裝成COM,這個工具也是頗有用的,若是你要用你的.NET assemblies去替換原有的COM組件,就得用到它了。由COM+提供的服務不能被忽略,因此把.NET assemblies封裝成COM組件就變得至關重要了。做爲一種選擇,開發者能夠從.NET基礎類庫中選擇更多的功能。程序員