組件(
Component
)應該是在現代軟件工程中,除了對象(
Object
)之外的第二個炙手可熱的詞了。然而,什么是一個組件?是一個某些邏輯集合的實現?還是一個承載這些實現的物理實體(例如
DLL
)?還是一個包括了邏輯實現、物理載體以及相關的類型信息、安全策略和版本信息的一個大而全的集合?也許你會說任何一種解釋都是正確的。的確,不同的環境中,
Component
有著不同的含義,但是,在
.NET
中,我們就可以把一個
.NET Class
當作一個
Component
。
既然類和組件有著這么多類似的地方,那么傳統的面向對象編程和面向組件編程有什么區別呢?簡單的說,面向對象關注的是組合在一個二進制可執行文件中的各個類的關系,而面向組件的編程關注的是在彼此獨立的基礎上模塊之間的交互性,這種交互性使得你并不需要熟悉它們內部的工作原理。
分而治之 VS 集大成
這兩種方法最基本的不同在于它們對最終的應用程序的觀點。在傳統的面向對象編程中,盡管你可以精心的把所有的商業邏輯分布在不同的類中,一旦這些類被編譯,它們就被固化成了一個巨大的二進制代碼。所有的類共享同一個物理單元(通常是一個可執行文件)、被操作系統認為是同一個進程,使用同一個地址空間以及共享相同的安全策略等等。如果多個開發者在同一份代碼上進行開發,他們甚至還要共享源文件。在這種情況下,修改一個類可能會讓整個項目被重新鏈接,并重新進行必要的測試,更嚴重的,還有可能要修改其他的類。但是,在面向組件開發中,應用程序是由一系列可以互相交互的二進制模塊組合而成的。
一個具體的二進制組件可能并不能完成什么工作。有些組件是為了提供一些常規服務而編寫的,例如通信的封裝或者文件訪問組件。也有一些是為了某些特定應用而專門開發的。一個應用程序的設計者可以通過把這些不同的組件提供的功能粘合在一起來實現他們需要的商業邏輯。很多面向組件的技術——例如:
COM
、
J2EE
、
CORBA
和
.NET
都為二進制組件提供了的無縫鏈接的機制。而唯一的不同就是你需要在組件通信上花費的力氣。
把一個二進制應用程序分解成不同的二進制組件的動機和把不同的類放到不同的文件中是類似的。后者使得不同的類的開發人員可以彼此獨立的工作,盡管即時修改了一個類也要重新鏈接整個應用程序,但是你只需要重新編譯被修改的部分就可以了。
但是,面向組件的開發還是和簡單軟件項目的管理更復雜一些。因為一個面向組件的應用程序是一個二進制代碼塊的集合,你可以把組件當作是
LEGO
的積木塊一樣,隨心所欲的拆裝它們。如果你需要修改一個組件的實現,只需要修改那個組件就可以了,而組件的客戶機不需要重新編譯也不需要重新開發。對于那些不常用到的組件,組件甚至可以在一個程序運行的時候被更新。這些改進和增強使得組件可以立即進行更新,而所有該組件的客戶都將立即受益。無論是在同一臺機器上還是通過網絡遠程訪問。
面向組件的應用程序也更易于擴展。當你需要實現新的需求的時候,你可以提供一個新的組件,而不去影響那些和新需求無關的組件。這些特點使得面向組件的開發降低了大型軟件項目長期維護的成本,這是一個最實際的商業問題,也正是如此,組件技術才如此迅速的被接受。
面向組件的應用程序通常可以更快的響應市場,因為你可以有很大的選擇空間,不僅僅是自己開發的組件,還可以從第三方廠商來購買某些組件,從而避免了重復制造輪子。這里,
VB
就是一個很好的例子,豐富的
ActiveX
控件使得很多人在快速開發中得到了享受。
接口還是繼承
面向對象和面向組件另一個重要的不同在于這兩種技術在繼承和重用模型上的側重點不同。
在面向對象的分析和設計中,應用程序通常被分解成復雜的類繼承結構。類的設計和要解決的商業問題緊密結合。你可以從已有基類繼承并特化其行為來實現代碼重用。問題在于,這是一種很糟糕的重用的方法。當你從一個基類派生一個子類的時候,你必須對基類的實現有透徹的理解才可能保證不出問題。例如:修改一個成員變量會不會帶來副作用?這會對基類中的代碼有什么影響?重載基類的方法會不會破壞那些想使用基類版本的客戶的行為?等等。
這種形式的重用被稱為白盒重用(White-box reuse),因為當你重用的時候你就需要去了解基類實現的細節。顯然。白盒重用在可擴展性較高的大型應用中并不經濟,也很難得到第三方Framework廠商的支持。
面向組件的開發采用了黑盒重用(Black-box reuse)的方法,它可以讓你對組件內部全然不知的情況下來使用組件公開的接口。這樣,你就可以遠離那些復雜的繼承關系。而面向組件的開發者也可以把更多的精力放在制定組件和客戶的溝通的接口上了。
最后,面向對象編程提供了有限的工具和設計模式來處理和應用程序運行時相關的問題,例如多線程、并發管理、安全、分布式應用和版本控制等。面向對象的開發者當面對這些“公共需求”的時候,或多或少的需要自己來解決問題。但是面向組件的開發方式卻使你在這方面要靈活的多。