元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文

仲強發表於2019-01-14

同步github:何構建一套出色的元件系統
同步cnblogs:元件化設計:如何構建一套出色的元件系統
同步知乎專欄:前端路上的摸索

寫在前面的話

  寫了好多年業務,想輸出一套前端的UI元件系統,但是對元件這個概念不是很深入瞭解,所以參考了很多資料,以及結合自己的理解,做出歸納和總結。所以才有了這一篇,從什麼是元件,到什麼是軟體中的元件化設計,再到元件設計中有什麼優勢和挑戰,到最後如何構建一套出色的元件系統。每個人的想法都不是一樣的,所以這一套元件設計思想,可能也並不完善,僅作為大家的參考,也歡迎大家補充。

什麼是元件

元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文

這就是我們現實生活中,最形象最貼切的物品了。

  圖一是一堆齒輪驅動的機器,每個齒輪都是單獨存在的,如果一個齒輪壞了,我們只要替換下來換一個好的就好了,這個機器一樣跑起來啦。

  圖二是個人PC的主機板,大家也特別熟悉,對於插在主機板上的每一個單獨功能的元件,如果壞了一個,可以換一個好的,通過插槽替換上去,也可以跑起來了。


所以生活中有很多元件的實體,我們看看這些關於元件的定義:

  1. 供裝配整臺機器、構件或元件的零件組合

  2. 在電子或機械裝置中組裝在一起形成一個功能單元的一組元件

  3. 組裝產品(如書櫥或碗櫥)時所組合的通常或多或少重複的部分

  4. 可被組裝或被重新組裝的幾個部件之一


這些都是我們看得到,摸得到的,下面我們再跳出現實表象,上升到一個更高的層面去看問題(這樣的高逼格的說法叫抽象)

  圖三是一個完整的中國地圖,地圖上每個省級的地域,我們不管你在這片區域是平原、高山、還是海島、還是大海等,只要你屬於規劃範疇,那麼就屬於一個省級區域,由這些區域組成了我們一個完整的國家,丟一塊都不行。我們可以把每個省級抽象成一個元件,國家機器,就是由這些元件一起跑起來的。


我們將資訊進行彙總和整理,得出如下結論:

  1. 從外觀和功能上來講,他們都是一個獨立的部分,可能是零件或者是原件

  2. 從行為上來講,他們擁有組裝這個屬性,可以和其他元件相互組合

  3. 可以被重新組裝,重複利用


  當然我們做軟體設計的,也是通過參考現實,抽象到軟體設計中,然後根據落地環境,去實現元件化設計思想,前人已經走在了路上,去摸索這塊土地,也獲得了一些實用的理論,比如基於元件的軟體工程(Component-based software engineering,簡稱CBSE)基於元件的開發(Component-Based Development,簡稱CBD)的軟體開發範型等等,有興趣的可以自己去看下。


下面是前人對元件的定義:

  1. 一個不透明的功能實體,能夠被第三方組裝,且符合一個構件模型。 — 卡耐基梅隆大學

  2. 是軟體系統中具有相對獨立功能、介面由契約指定、和語境有明顯依賴關係、可獨立部署、可組裝的軟體實體。 — 計算機百科全書

  3. 是一個組裝單元,它具有約定式規範的介面,以及明確的依賴環境。構建可以被獨立的部署,由第三方組裝。 — 軟體構件著作

  4. 為自包含的、可程式設計的、可重用的、與語言無關的軟體單元,軟體元件可以很容易被用於組裝應用程式中。 — 百度百科

  5. ......


每個結論針對的都是各自穩定軟體領域的抽象,我們還可以看到更多對於元件的定義。所以我們針對這些結論,做一個總結,元件具有什麼樣的特性?

  1. 高度內聚,不透明 — 不需要關心這個東西怎麼搞出來的,知道怎麼用就好了

  2. 對外以介面契約 — 有說明書,知道這個東西給了需要的就變成你想要的

  3. 功能相對獨立 — 相對概括的指明這個東西的使用途徑

  4. 環境依賴 — 對環境的依賴比較重要

  5. 可重用 — 可以多次使用

  6. 可組裝 — 可以和其他東西組成其他的玩意


什麼是元件

  原子元件:原子級別元件,單一功能,不能繼續拆分。

  複合元件:多元件組合,組成的能完成某一功能的元件。

  插槽元件:為元件的組裝完成一個功能而提供的基礎設施。

  擴充元件:在原有元件上派生出一個新的元件,為原有元件增加新的效能或者更改原有元件的功能。

  適配元件:通過適配元件去封裝不同元件,保證對外契約一致


什麼是元件設計思想?

  將需求場景領域化,將場景領域模組化,以符合系統需求為衡量,以穩定領域最大複用為目的,使其可以通過組合拆分來構建整個系統的獨立解決方案


如圖:

元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文


案例:

  比如我們需要做一個簡單的前端的活動系統,需求要有登入系統、檢視活動、建立活動、修改活動、刪除活動。


將需求場景領域化:

  登入系統 --> 表單提交
  檢視活動 --> 資料展示
  建立活動 --> 表單提交
  修改活動 --> 表單提交
  刪除活動 --> 行為操作

  ==> 抽象出表單提交、資料展示和行為操作這些穩定領域


場景領域模組拆分:

  表單領域拆分模組(簡單拆分2個)
    1.文字輸入模組
    2. 密碼輸入模組
    ......

  PS:其他領域跟表單領域一樣,進行模組拆分。


概括共性:

  比如表單領域的2個簡單模組,我們需要對其概括共性,

   1. 他們都是輸入的文字

   2. 一個輸入文字可見,一個輸入文字不可見。

  結論:我們可以設計一個輸入文字的元件,對外開放契約,如果你告訴我你需要把輸入不可見,我內部就做處理將這些東西遮住。


產出元件:

  元件:輸入元件

  契約:是否需要遮擋輸入

  功能:輸入文字的

  領域:表單輸入使用


設計意義:

  以這樣的方式做元件設計,如果整個系統都有這樣的穩定領域,那麼這些元件的意義就是針對該系統是最好的,不僅滿足了需求,還可以最大功能複用。


元件化設計的好處?

  1. 可重用,對於一個功能獨立且單一的元件,不需要花費其他資源,可以直接使用元件達到效果

  2. 擴充和替換,對於系統的維護和更新來說,可以通過基礎元件進行擴充,然後可以通過替換元件去為系統進行更新

  3. 複雜合作可能性,獨立拆分模組和元件,已元件拆分組合構建完整系統,使大型專案合作成為可能。

  4. 提高效率,這包括對軟體複雜性更有效率的管理,快速地推向市場,以及更高的生產力(迭代效率),更高的質量等等


元件化設計開發有什麼挑戰?

  1. 開發元件所需要的時間和精力。

  開發元件不是單獨完成一個功能或者一個頁面,如果開發成元件,所需要的時間和精力成本是遠遠大於只是純粹完成一個功能的成本的。

  1. 不可描述需求的開發。

  對於軟體的需求階段,在現實開發中,不可能是所有需求都特別明確的,所以對於這些不定性,不可描述需求的開發,對於元件的挑戰是很大的,因為領域不穩定,最終可能抽象的元件也是不定且變化的,這樣導致的元件變化成本是急劇上升的。

  1. 可用性和可重用的衝突。

  對於系統中最後形成的元件的衡量,不是一個固定標準的。可能元件對於現階段的可用性已經完全滿足,但是對於未來變化和爆發是否需要前瞻性的做預留和擴充,以達到更高一層的可複用的衝突,需要開發者自己衡量的。

  1. 元件維護。

  元件的維護在小型專案還可以忽略,但是在大型專案中,如果維護需要自己一個程式碼一個程式碼的去尋找痕跡,那麼這樣的元件設計開發不理想,反而違背了元件設計最初的夢想。

  1. 可靠性以及容錯機制。

  因為元件內部是相對獨立的,我們不知道內部的變化,所以衡量一個元件除了是否滿足我的需求以外,是否可靠,以及元件不可靠,出現意外的反應機制是否能夠準確定位和降級容錯(損失一些功能,保證其他功能完善)。

  1. 持續增長的挑戰。

  元件開發是為了更高的減輕開發中的各種負擔,但是在元件持續的增長中,元件本身也會成為一種負擔,對於本身的負擔是否有完善的處理機制,可以在持續增長中hold住。

  1. 元件的規範。

  每個攻城獅的開發風格都有各種差異,元件的規範,在這樣的合作中就是重中之重,減少多套理解成本。

  1. 解析元件的“核心”。

  對於核心大腦的健壯是整個系統的靈魂。這個不多說,掛了就直接game over!

有挑戰,是真實存在的,但是我們可以通過一系列的方法和規範去解決這些挑戰,讓元件化設計更好的服務我們的系統。


如何設計一套出色的元件系統?

元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文


構建元件系統有2個方向:
  設計一套符合系統需求的元件
  設計一套可以通用的元件


羅列一些不管哪個方向都要考慮的因素:

1.統一收口和管理元件

  對於任何一個系統來說,快速迭代和增長中勢必會帶來元件的爆發式增長,如果不能將元件統一收口,可能會帶來元件的重複開發利用率低下(可能和一個元件功能80%相同,只需要擴充一個原子元件就可以解決問題。或者無收口不知道其他地方有個類似可以滿足的元件導致二次開發)。其次管理也一樣,好的管理可以最大化發揮元件式開發的優勢,不善的管理就會帶來這樣的疑問,"這樣的元件化開發,增加了更多的複雜度,還有什麼意義?"


2.元件升級和更新,乃至替換做到可控

  忘本式迭代,拋棄舊包袱,迎接新時代這是一種很爽的開發體驗。但是也會帶來,開發一時爽,xxxxx(大家自己體會)。元件每次的升級,在沒有完整的方案前,勢必要考慮元件的相容性,否則我每次迭代一個新的元件,使用的元件都不相容,都需要從頭返工手把手替換使用的元件。那就呵呵了。但是有完整灰度方案以後可以實施,比如元件整體升級2.0版本,才能使用新特性,且有足夠的元件升級遷移方案保證升級無影響。這樣的可控,可以最大化元件開發的優勢。


3.容錯,核心與非核心元件的容錯方案的處理。

  容錯式,也分很多種方式,在傳統window大型系統中,對於核心元件的容錯式就特別的低,因為有些是核心元件,比如CPU,丟了這個就不能玩了。但是對於USB插槽,音訊輸出插槽等等這些容錯率就很高,你壞了無所謂,我係統能跑。只是我會斷掉你的元件提供的功能。所以元件的容錯,需要針對系統本身去評估,無統一方案。


4.安全性,除對外暴露契約影響,對內應自成沙盒

  這個就跟瀏覽器一樣,我受影響的東西,只有我自己對外丟擲的約定和契約,否則其他東西都不能影響到我。這樣才不會導致會有非本身的變動,而讓元件自身出現問題,解耦萬物,才能達到內心的聚合和獨立。


5.文件,元件的自描述,功能和對外契約

  沒有文件就是沒有自我介紹,誰知道你是誰,能幹什麼,能不能勝任我的解決方案。


6.可信,元件開發授於任何開發者,必須減少風險的可能,以及全面的測試。

  元件設計最終的執行者是開發者,如果一個未受評估或者沒有全面測試的元件引入整個系統構建中,那麼就是引入了一個很大的風險,以後對於這個風險你可能會承受多餘自身的時間去把控這個問題。這也是一個合格的軟體開發工程師需要評估的問題。


7.介面卡和膠水程式碼:包裝更復雜複合通用元件,應通過介面卡設計和膠水程式碼組合,保證符合元件規範

  元件的重複利用和元件之間的組裝,肯定會帶來更多元件的出現和更復雜的元件出現,自然而然會得到更高的複雜度。但是基於本系統的元件規範和開發規範,可以使用更多的膠水程式碼去適配成和本系統元件一致的模型,這樣你我都一樣,學習和使用成本都不高。業內很多都是建立一個元件的原始類,定義元件的基礎功能和契約,所有的元件都會去繼承這個原始類,達到元件的一致性。


8.友好,對開發者更友好,學習成本和使用成本更低廉

  在軟體開發中,下游消費的是程式設計師,是將你建立的東西發揚光大的信教徒,你的佈道需要更多的友好。否則程式設計師內心就會出現這樣粗俗的聲音,“你上來就給老子一棒子,寫著寫著又給老子一棒子,還玩個蛋!”


9.穩定,一切以穩定為重,遠離危險程式碼

  相信每個公司都會安利這樣的思維,生產程式碼是能經歷風吹雨打,是能扛得住大山的。你的元件一樣必須這樣,太多的問題,最終會導致無法維護,成本太高,問題千奇百怪等等,然後你被幹掉了。


10.特色,獨特的系統有自己的特色和亮點

  一般這個都是可選項,畢竟你想的輪子,可能前人都造了N個,你有什麼特色去讓別人去選擇你,使用你。是因為愛嗎?還是因為愛嗎?


11.更符合使用者習慣

  站在別人的角度去思考問題,才能知道別人需要什麼,才能讓別人離不開你。


設計一套符合系統經需求的元件(面向需求的元件開發)

元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文

第一要素:以需求為中心,以滿足需求為衡量標準

1.挖掘符合本系統的元件做基礎元件和樣本元件。

  一個系統的元件系統很少是自己從頭搭建,因為成本問題。在業務的快速迭代中,一般都會選擇一些提供原子元件的第三方的庫和包,通過包裝第三方的元件,形成符合本系統需求的元件系統。


2.構建需求元件,適應現有系統的元件模型和需求規範

  不同元件定義了自己不同的對外介面契約,千變萬化的契約會帶來雜、亂、差。不管哪一方的元件,乃至自己的元件,都需要遵守本系統的元件模型規範。


3.可選擴充,在需求可伸縮範圍支援擴充和收縮

  在需求元件的開發中,對需求的發展,乃至回滾都有很清楚的認識。在這樣的基礎之上,可以在元件開發中留有可選擴充項,需求伸縮和回滾都能把控。


4.適可而止,不過多設計

  一切以需求為準,滿足即是最好。


5.自描述性更高,元件設計對需求的耦合性更高,需要更多的描述

  因業務的複雜度耦合更多的獨特的規則,這樣的元件更需要更高的自描述性內容。


設計一套可以通用的元件(面向複用的元件開發)

元件化設計:如何構建一套出色的元件系統 | 掘金年度徵文

第一要素:以通用為中心,以抽象共性解決同類問題為衡量標準

1.關聯穩定的領域抽象

  通用,即是穩定的,形成共識的領域。所以通用元件,也是穩定領域抽象出的元件


2.將元件一般化

  一般元件都是為了解決特定問題而產生的應用,將這個應用進行一般化,關聯更普遍的業務物件


3.控制複雜度和可讀性

  越通用的元件,可複用性越高,但是複雜度性對也越高,可讀性也越差


4.一致性

  統一的介面和契約,乃至統一的對外異常暴露,只有大家越一致,更通用才會成為可能


5.適應性

  為元件增加一個配置介面,為元件伸縮提供一種可能


針對元件設計的挑戰,我們從未因為有挑戰就停止前進的步伐,所以結合前人探索和自己開發中的經驗和理解,對於想構建一套出色的元件系統的各位攻城獅提供一個指南和參考。

後記:

  如果你感覺對你有用,請點個star,繼續支援我更多的研究。

  如果有任何問題,請到這裡提issues,一起探討問題的可能性。

掘金年度徵文 | 2018 與我的技術之路 徵文活動正在進行中......

相關文章