框架-設計 : 要點總結
框架設計要點總結
*/作者:zonebond/*
框架設計
框架是服務開發人員的,而非限制開發人員。如何讓使用者發揮效率,又能引導其實現更具靈活性的功能設計。是框架的本質。
框架本身並不關注業務,至少不受業務影響或制約。框架就是要從具體的業務功能中,分離出能覆蓋所有業務的設計、實現與組成。並使得各業務功能從開發實現的角度,變的解耦合、可重組、易維護。
框架也會進化,其進化過程就是一個設計權衡的過程。一個典型的設計權衡過程就是目錄結構設計。
目錄結構設計方法,一般有兩種:一種是以類型劃分,一種是以業務劃分。
以類型劃分目錄結構的特點是,遵循代碼分層架構,分類不同層的代碼。如:以MVC架構為例的目錄結構特點就是,所有的Model模型放在同一目錄下,所有的View視圖放在同一目錄下,所有的Controller控制器(或叫業務邏輯)放在同一目錄下。
```- src |- models |- views |- controllers ```
這樣劃分的好處是,當你理解和接受MVC架構設計思想後,就能很輕易的做到代碼結構分離。簡單粗暴,但非常容易理解。這樣劃分的缺點也很明顯,當項目業務變多,變複雜時。這種簡單粗暴,就變得難以維護了。首先就是龐大的業務導致單一目錄下更多的代碼文件。再者,就是你很快就會發現有些業務很難明確的劃分到MVC中的某一層去,然而這些業務通常都會被放在了控制層。這導致一個可怕的事實,控制器內容變多,原本清晰的控制層變的不那麼清晰,文件和文件內的代碼變的難以維護。相比之下視圖層與模型層比較容易劃分。
以業務劃分目錄結構的特點是,以業務功能的形式組織代碼,甚至可以將大業務拆分成小的業務組成。
```- src |- module_A |- module_B |- module_C```
這樣劃分的好處是,同一業務代碼都聚合在同一目錄內,不會受到其它代碼的干擾。因為業務結構通常是跟需求設計相關聯的,需求通常是已經收集或設計好的,這也使的劃分業務更容易,也更具有業務通用性。另一方面,在設計實現時,思路也更聚焦在業務內。但單純的以業務劃分目錄結構的缺點也很明顯,不同業務可能存在代碼實現冗餘,代碼重用度不高,導致業務代碼文件大,模塊文件數量變多,不易於維護。
所以,在設計目錄結構時,權衡兩種方法,將其優勢結合在一起使用,就可以發揮出好的效果。
例如,一般可以將提出公共部分的代碼,放到組件或公共代碼目錄里,將各種公共資源(非代碼文件)放到資源分類目錄里,並且在此目錄下做業務或類型的子目錄加以區分。再將業務功能代碼組織在模塊目錄內,以業務名稱命名子目錄的形式分類。此時的目錄結構就具備了類型與業務劃分的兩種優勢。再者,可以在具體業務目錄內,將業務功能代碼再以類型(如MVC分層)的方法更細粒度的劃分,再在大的業務目錄內拆分出小的業務目錄,就使得代碼目錄結構,更加清晰,易於維護。
```- src |- assets |- commons |- components |- modules |- modules_A |- modules_A_1 |- modules_A_2 |- modules_B |- views |- models |- controllers |- pages```
最後,目錄結構設計還有一個要考慮的問題,就是文件內引用其它文件時,使用到的相對或絕對路徑的長度的問題。要引用的外部文件路徑儘可能的短,會使其更容易維護。
框架的最核心作用是標準化開發。在框架引導的設計思想下組織代碼,就能使代碼標準化。例如,Web前端架構要求一個功能模塊應該具有:
```> 視圖層:視圖 + 路由 + 皮膚> 業務層:業務 + 模型 + 服務> 傳輸層:傳輸 + 數據管道> 開發層:API交互模擬 + [DEMO模式]> 單元測試```
以上面的設計做實現,即使代碼風格不同(在使用技術相同的情況下),也不太可能寫出差異很大,且不能被他人維護的代碼。
框架使業務模塊聚合、使模塊內容聚合。
組件設計
`我們不會討論公共組件與業務組件,因為它們是一樣的,只是範圍的問題`
組件的設計核心應該是面向開發人員的。完成組件的功能,那是最基本且必要條件中最不需要討論的方面,並且如果僅僅是完成功能的話,這樣的代碼也算不上組件化,那僅僅、最多是一段代碼而已。沒有什麼可重用或提高開發效率可言。即使在功能上被多個模塊使用,也只能說明,這些功能模塊內都具有一模一樣的業務點僅此而已。
不能覆蓋通用的場景就不能稱之為組件。隨著業務和功能的深入與增加,你很快就會發現,這樣的代碼不能在相似但有差異的業務功能場景中被重用,即便是很小的差異點。甚至可能是,相同的功能,不同的數據模型時,也不能被使用。
真正的組件設計, 要點有兩方面:一是通用,二是易用。
通用這一點,是要求組件設計思路抽象化。只要抽象出組件業務所對應的「通用責任」,才能做到通用,靈活,可擴展。
組件化的目標是以代碼重用和高內聚來提升開發效率,降低維護成本,以達到業務的快速演進。只要組件設計的「通用」,這一點不難實現。與「通用」這一點相比,另一個要點「易用」更重要。
幾乎會每一個開發者都有組件化的意識,並且也有在做組件化。但是並沒有達到預期的目標和效果,或者效果甚微。其重要的一個原因是,大多數組件開發者並沒有把「易用性」放到重要方面來考慮。大多數人只是為了實現組件功能而做組件。這樣做出來的組件,在功能上確實也能滿足要求,但使用起來代價很大。往往會給使用者帶來困擾,甚至影響開發效率。
另一方面組件最終面向的是開發人員。組件的易用性設計,其實是對組件與組件使用方式的設計與權衡。換句話說就是組件的API交互介面設計。
這裡有一些簡單的設計原則:
```> 使組件使用者儘可能不寫任何代碼,盡量在組件內部完成條件收集> 如果一定要使用API,要簡化API。能用一個參數的,絕不要求兩個或更多> 高內聚,低耦合。組件內多做事,組件外就少做事> 使用設計模式實現組件,以達到「通用軟體責任分配」實踐> open-close原則:對實現開放,對修改封閉```
最後,好的組件化,更會使得實現的代碼標準化。使項目更易於維護。
關注分離
在做一件事時,不去想這件事與另一件事的關係如何,只專註於這件事本身。而把事件之間的關係也當成一件標準的事件去做,而不用考慮具體是哪些個事件的關係。這樣做就是將關注點集中在一件事上考慮,就能做到更快更好的完成這件事。
儘可能得使開發者只關注業務代碼,而不被業務代碼之外的其它任何因素影響。例如:在做項目工程化時,把工程化腳本與資源都內聚在特定的目錄下,一個與項目代碼無關的目錄下,減少對開發人員的影響。使開發者能更關注實現業務功能。
易於聯調
在項目開發過程中,前後端聯調往往要花費很多的時間。首先要等兩方都基本開發完成後。其次,要搭建適合建聯調的環境。再者,聯調本身不可預測的問題修改,會導致極其低的完成效率。
實際項目開發中,往往都會要求前後端優先協商API介面或調用約定。相比之下,後端有一些成熟的工具來模擬API調試。
前端API交互模擬工具,能很好的解決這個問題與提高聯調效率。因為,API做為前後端交互約定,在共同協商設計時已經完成。只要前端按照API約定的要求,構造數據,就能完成前後端交互模擬。雖然,交互本身不是真實的前後端數據交互。但對於前後端各自己都能在不用等待對方的情況下,完成基於API協定的交互過程,可以減少前後端開發進度的依賴,也能儘早的暴露問題。等到了真實聯調時,問題就會少很多。
前端API交互模擬工具的另一個好處就是,減少對調試開發環境的依賴。沒有環境也能做API模擬。使各端都可高效開發。此工具如果不需要後台支持,往往都需要Mock機制與Mock數據。使用Mock的好處除了可以做API交互模擬去獨立伺服器調試代碼外,還可以為單元測試做鋪墊。想像一下,如果Mock邏輯覆蓋了所有的代碼邏輯,事實上單元測試就變的很容易構建了。
這裡推薦一個自己實現工具庫:v-block.net 是一個可以攔截http請求與響應的組件。它是在瀏覽器上工作的,不依賴於後台真實的API服務。此組件能夠修改原始請求與響應結果,所以,在很多需要對http統一處理的業務場景非常有用(如:請求header統一加token等)。並且,此組件可以與其它任何ajax組件配合使用(如:fetch、axios、requrest...)。 可以在 yarn 或 npm 上找到。
----------------------------------------------------------------------------------------------------------
*`zonebond`**`Email: zonebond@126.com`*
推薦閱讀:
※一名Infrastructure Engineer需要掌握哪些技術?
※報表和數字背後的秘密:重點內容整理
※業界主流的RPC框架有哪些?Dubbo與Hadoop RPC的區別?
※框架到底是個什麼東西?
※基於 Ruby 實現的移動 App 自動化測試框架 (AppiumBooster)