如果你在京東圖書頻道搜索 組件化 或者 組件化開發,顯示的幾乎都是 Android組件化開發 或者 Android組件化架構 等等。類似Android這樣的技術,它們本身就是可組件化實踐。
再一個就是JS前端框架,在這個領域裏也常常提組件化,比如VUE框架是組件化的實現,通過Vue.component來實現組件化開發,通常一個組件也就是一個小型的vm實例,前端的程序員同學大都在實現組件化的路上努力着。
我本身並沒有開發過Android的應用,對JS也逐漸陌生,只是工作環境中接觸這兩個領域下的組件化。這篇文章我想說的是其它語言系統架構的組件化,比如JAVA。我們在架構的環境裏面將組建分爲兩種,分別是可依賴和可配置。
可依賴
系統架構環境內的組件化,第一種是我們很常見的比如Apache下的commons包裏面的類,我們工程裏面幾乎都會依賴,還有就是我們自己寫了一組方向相同的類並組裝成一個包,供其它模塊來調用。
究竟哪些類應該被組合成一個組件呢,正如《架構整潔之道》這本書中所介紹的,這是一個非常重要的設計決策,應該遵循優秀的軟件工程經驗來行事。
這些優秀的實踐經驗,凝結成了三個與構建組件相關的基本原則,分別是
REP:複用/發佈等同原則
軟件複用的最小粒度要跟發佈的最小粒度相同
CCP:共同閉包原則
有些類經常同時修改,並且修改的目的也相同,這些類應該放到同一個組件中
CRP:共同複用原則
不應該強制某一個組件的使用者去依賴他們不需要的東西
不過,我們在利用這三個原則的時候會發現,他們之間是一種競爭的關係,也就是不可能同時遵守,但如果只考慮其中的兩個原則而忽略另外一個又會帶來系統架構上的壞的後果。比如,只關注REP和CRP就會導致太多組件變更;只關注CCP和REP就會導致很多不必要的發佈。下面這張圖是組件聚合三大原則的張力圖,圖中的邊線表示如果只考慮兩種原則而帶來的後果。
那麼,我們應該如何做出取捨呢。還是參照上面這張圖,《架構整潔之道》一書中給我們的建議是,我們考慮設計一個軟件架構的時候,剛開始重心從張力圖中的右側開始,這個時候犧牲的是複用性。隨着時間的推移,軟件逐漸成熟的過程中,會對其它組件產生依賴,重心就會朝向張力圖的左側移動,從而開始考慮軟件架構的複用性。
可配置
對於系統架構層面上的組件化,一個系統或者一整塊大的功能,支持了很多種類型的業務場景,比如既支持了POP的業務,又支持了自營的業務;再比如既支持了國內,又支持了國外,一套代碼全球部署。那麼我們說以上這樣的方式也可看成是國際化的部署。
在部署不同站點的同時,可以實現積木的方式搭建且按需部署。有時候需求方僅僅是需要一個最小的子集。比如,汽車能跑起來,主要因爲有發動機、車輪、懸掛、車軸等,這些是最基本的組成;象後視鏡、真皮座椅、自動防碰撞、自動駕駛等等這是增配部分。系統也是一樣。
下圖是一個系統組件化的概念結構圖,包括基礎服務層、業務服務層、業務應用層和業務場景。基礎服務層是站在自身系統的角度去說,我們的依賴方,往往都是強依賴,缺少了不行的。業務應用層是我們的組件化可以支持的業務,業務場景在上文有提到。其實重點還是業務服務層,這一層是組件化的重點。
依照此圖舉例,業務服務層我們首先豎着分爲七大模塊,也就是這個系統或者這塊業務一共分爲七大可組件化的內容。其次用一條橫線上下分爲基礎組件和增值組件(或者成爲高配組件)。最後,一個方框圈住我們要面對的業務可組件化的最小子集。我們簡稱爲:一豎、一橫、一個方框。
模塊、組件、插件
我們本文探討的是組件,但另外兩個內容常常被在一起說起,也就是模塊和插件。在我看來它們三個是同質不同形的事物。模塊是組件的基礎,一個軟件系統沒有模塊化則無從談起組件化,試想一個大泥球的系統自身都分不清了,何談組件化呢。模塊化也很好理解現代化的開發工具比如IDEA,我們在使用的時候,每次創建的工程都是一個Module Project,類似下圖這樣。
說起插件,也可以舉一些我們平時工作中常見的使用場景。比如Chrome瀏覽器中我們會下載安裝插件,以便幫助我們更高效的處理我們的工作,Eclipse中的插件也是如此。象舉例的這兩種插件,它們都是成型的產品對接,使我們動態的"插入"到比如Chrome這個"大軟件"系統裏面。如何跟組件區分呢,組件大多數時候是在"編譯"過程中的依賴,當然 上面提到的可配置的組件,也有插件的影子和"味道"。
模塊是最基礎的事物,它們是組件化、插件化的前提,是任何一個軟件系統想要解耦的基礎。組件是一個範圍更廣的定義,比插件的包含範圍要大,也可以說插件是特殊的組件。我本人倒是覺得不必要太在意它們之間的區別,可以直接進化到 "看山不是山,看水不是水"的階段,理解那個意思就好。
總結
組件化的好處,解耦。實際上組件化開發之後可以更快速的交付,節省需求響應處理時長,這也是業務人員所在意的,研發人員所看重的。當需求來了之後,可以通過配置化,幾乎不用動代碼,就像搭積木一樣滿足了業務方的需求,這一定是很爽的一件事情。誠然,這也是非常有難度的一件事情,因此組件化的開發,任重道遠。