面向對象技術的基礎是封裝--接口與實現(xiàn)分離,面向對象的核心是多態(tài)--這是接口和實現(xiàn)分離的更高級升華,使得在運行時可以動態(tài)根據(jù)條件來選擇隱藏在接口后面的實現(xiàn),面向對象的表現(xiàn)形式是類和繼承。面向對象的主要目標是使系統(tǒng)對象化,良好的對象化的結果,就是系統(tǒng)的各部分更加清晰化,耦合度大大降低。
面向組件技術建立在對象技術之上,它是對象技術的進一步發(fā)展,類這個概念仍然是組件技術中一個基礎的概念,但是組件技術更核心的概念是接口。組件技術的主要目標是復用--粗粒度的復用,這不是類的復用,而是組件的復用,如一個dll、一個中間件,甚至一個框架。一個組件可以有一個類或多個類及其它元素(枚舉、)組成,但是組件有個很明顯的特征,就是它是一個獨立的物理單元,經常以非源碼的形式(如二進制,IL)存在。一個完整的組件中一般有一個主類,而其它的類和元素都是為了支持該主類的功能實現(xiàn)而存在的。為了支持這種物理獨立性和粗粒度的復用,組件需要更高級的概念支撐,其中最基本的就是屬性和事件,在對象的技術中曾一度困擾我們的類之間的相互依賴問題/消息傳遞問題,迄今為止我所知道最好的解決方案就是事件。要理解組件思想,首先要理解事件的思想和機制。
我一直堅持以為,一個組件的外形/外貌應該是簡單的、應該是清晰的、沒有冗余的東西、也沒有無關緊要的東西,這個外貌通過接口來描述,接口中可以發(fā)布事件、屬性和方法。這三種元素就足以描述一個組件外貌的所有特征。比如,我曾經用封裝的一個完成端口組件,其外貌接口中只有四個方法,三個事件,三個屬性而已,而該組件的內部實現(xiàn)卻有幾千行代碼。所以在設計一個組件的時候,需要做很多的權衡,哪些需要通過接口暴露出來,哪些應當作為私有實現(xiàn)。有時,你會處于兩難的境地,因為讓組件更容易使用,所以需要給出很多默認的參數(shù),但為了使該組件更通用,你又需要暴露更多的屬性可以讓人設定、暴露更多的方法和事件滿足更復雜的功能。你需要抉擇,你需要權衡。難怪有人會說,軟件的設計更像是藝術,因為藝術的美在于恰當?shù)木駬窈推胶狻N业慕涷炇牵诒3值婉詈隙鹊那疤嵯拢M件的接口足以對付當前的應用就好。如果日后需要加強功能,那就重構然后增強它,這是很容易的,因為早就說了嘛,保持組件的低耦合度。
需要說明一下的是,我們通常所說的控件(如按鈕)也是一種組件,可以這么認為,控件是一種具有UI形式的組件。插件(Addin/Plugin)也是一種特殊的組件,插件的單獨存在是沒有意義的,它是由兼容該插件協(xié)議的框架所使用。
最后強調一點,組件的目標是粗粒度的復用,組件的核心是接口。