- 前端架構:從入門到微前端
- 黃峰達
- 2933字
- 2019-09-21 00:53:47
1.3 架構設計原則
不同的人在設計架構時會出現(xiàn)不同的風格,在細節(jié)的把握上也會出現(xiàn)特有的風格,這便是架構的設計原則。筆者根據(jù)自己的項目經(jīng)驗,總結了三個設計原則,如下。
◎ 不多也不少:不做多余的設計,也不缺少關鍵的部分。
◎ 演進式:不斷地演進以使架構適應當前的環(huán)境。
◎ 持續(xù)性:長期的架構改進比什么都重要。
它們不是真實的架構需求,而是隱藏在背后的設計思想,也是不同人的設計價值觀。
1.3.1 不多也不少
一個好的架構設計,內(nèi)容不多也不少。增加新的元素,覺得有些多余;想刪除某個元素,卻又找不到更合適的。無論是藝術設計領域,還是計算機領域,原則都是相似且適用的。
設計過多則過度設計。即我們針對未來,提前準備好相應的設計。這些設計都是假想出來的,在實現(xiàn)的時候設計本身便不再適用。反而,我們還要解決之前的設計帶來的問題,重新修改、刪除原先的設計,它們會進一步增加項目的成本。不過,過度設計多出自規(guī)模較大的項目,參與人數(shù)眾多,某些地方如果不能進行預先設計,那么在實踐過程中會遇到一系列問題。
設計過少則設計不足。設計不足會使架構擴展性不強,不能靈活地應對變化。值得一提的是,設計過多有可能是設計者的癖好或是炫技,而設計不足則可能是能力有限。
對于過度設計或者設計不足,往往很難做到真正的平衡及適宜。尤其在出現(xiàn)過其中一個問題之后,很容易往另外一個極端發(fā)展。如我們在某個項目里設計過度,在下一個相似的項目里,就可能會因為刻意減少設計而導致設計不足;相似的,如果在某個項目里缺少了設計,那么在下一個項目里,可能又會出現(xiàn)過度設計。
此外,我們還經(jīng)常作兩種假設,一是未來的人會比我們聰明,所以少做了一些設計;二是未來的接手者會比我們略遜一點點,那么就會為他們多做一些設計。
對于低級別的設計來說,應盡量避免進入細節(jié)設計,寶貴的資源應該投入更緊迫的業(yè)務開發(fā)中。對于高級別的設計來說,不預先設計模塊和組件,僅從架構上考慮,即為未來預留擴展的空間。比如對于前端開發(fā)而言,為了將來在內(nèi)部開發(fā)自己的組件庫,當前可以通過適配者、代理模式對第三方組件進行二次封裝。
如果在代碼中為未來的代碼預留一定的空間,那么大多是會產(chǎn)生問題的。因為多余的設計,會影響系統(tǒng)的后續(xù)擴展,并且在修改相關代碼時,不敢放手去改,以滿足現(xiàn)在的需求。比如在設計前端組件的過程中,想到未來會添加某些功能,便預留相關的接口,便有過度設計的嫌疑。
架構都只是適合當前的情況,一談論到各種需求變化時,會發(fā)現(xiàn)架構設計上有各種不足,這并非是架構的問題。架構要不斷根據(jù)需求演進變化,以滿足新的需求。
1.3.2 演進式
適應環(huán)境能夠生存下來的物種,并不是那些最強壯的,也不是那些最聰明的,而是那些對變化做出快速反應的。——達爾文
開發(fā)模式不同,軟件架構的設計要求也不同:
◎ 在瀑布模式下,往往會預先設計好系統(tǒng)所需要的一系列要素,進行軟件建模、詳細的架構設計、文檔編寫,直至設計的工作完成。在項目實施的過程中,會嚴格按照這些設計來執(zhí)行。倘若架構有問題,那便是一個相當嚴重的事故。
◎ 在敏捷模式下,則是先有架構藍圖,實現(xiàn)對應架構的PoC(概念驗證)。然后在實現(xiàn)的過程中,基于PoC產(chǎn)生的代碼疊加業(yè)務代碼。接著,在項目實施的過程中,不斷地完善應用架構的設計,如軟件建模等。
這便是敏捷模式和瀑布模式的對比,采用敏捷模式是為了應對用戶需求的不斷變化。而需求的變化,則可能會和早期確認的方向不一致,與最初設計的架構不匹配。互聯(lián)網(wǎng)應用都是敏捷型應用,需要應對不斷變化的用戶需求,及時改進和調整架構。
瀑布模式采用的是完全計劃式設計,即在編碼前,由頂層至底層進行的一系列架構設計,包含了各個模塊、服務、函數(shù)和接口。而演進式架構,則是預先設計好重要的部分如模塊功能劃分、領域劃分等粗粒度,隨后在編碼的過程中,再進行函數(shù)和接口的設計與實現(xiàn)。
事實上,瀑布模式也無法采用完全的計劃式設計,因為無法事先對系統(tǒng)進行全面的了解。而即使是純粹的敏捷項目,也無法采用完全的演進式架構,還是需要結合計劃式設計。以軟件開發(fā)和設計領域的專家Martin Fowler的觀點來看,兩者間最合理的分配是20%的計劃式設計,80%的演進式設計。這樣的設計需要我們注意以下幾個方面:
(1)在項目初期進行計劃式設計,以確保架構能處理最大的風險。
(2)在迭代0進行初步的架構實踐,編寫示例的架構性代碼——以將設計原則、風格融入項目中。
(3)在項目實施過程中,采用局部設計或演進式設計,以應對需求變化。
(4)配合重構、測試驅動設計與持續(xù)集成等敏捷實踐,來驅動架構的實施,并防止架構腐爛。
在計劃設計階段,可以制定前后端分離架構的基本規(guī)范,如使用JSON作為API的數(shù)據(jù)格式,使用RESTful作為API的規(guī)范。同時,進行核心的技術選型,如選擇后臺服務的框架、數(shù)據(jù)庫等。對于前端界面的框架,則可以在項目的迭代0里進行更進一步的技術選型。在項目實施的過程中,如果發(fā)現(xiàn)工具不合適,也可以在適當?shù)臅r候嘗試使用更好的工具,它需要我們以一種變化的心態(tài)來看待架構在項目中的意義。
相似的還有諸如API的設計,我們可以在計劃設計階段進行API的功能定義。而真正的接口定義——返回的字段、詳細內(nèi)容和值類型則屬于詳細設計,可以在后續(xù)實現(xiàn)的過程中加以完善。
1.3.3 持續(xù)性
從某種意義上來說,持續(xù)性和演進式有些類似。兩者的區(qū)別是,演進式是指架構上的一些變化,而持續(xù)性針對的是開發(fā)人員的變化。架構的持續(xù)性原則的意圖是,敢于修正架構中的錯誤部分,在修正的過程中盡管可能會帶來一些不合適的中轉式架構,但是也會很快被糾正過來。具體地,持續(xù)性包括以下幾個方面:
技能水平的持續(xù)改進。隨著代碼的增多,架構也在不斷地變化,也需要不斷地被糾正,以符合現(xiàn)有的需求。這就要求團隊里的成員既要懂得現(xiàn)有的架構,還要有能力來做一些改變。為此,團隊成員需要在項目中進行相應的工程實踐。在日常的開發(fā)中,使用敏捷方法實踐相關的持續(xù)集成、持續(xù)部署。此外,還要關注與學習相關的技能和實踐,以協(xié)助我們改善架構。如Neal Ford所說,開發(fā)中善于發(fā)現(xiàn)抽象與模式,并借助測試驅動開發(fā),利用重構進行導向設計。并使用一些質量改善工具,用它們產(chǎn)生的指標來發(fā)現(xiàn)問題。
應用的持續(xù)改進。除了業(yè)務應用本身,互聯(lián)網(wǎng)應用還需要一系列的配套服務日志、用戶行為日志、性能監(jiān)控等。如果以互聯(lián)網(wǎng)公司的思維來看,這些事件都不會是一蹴而就的,“先上線,后解決問題”才是真理。在項目開始階段,某些部分可以手動來完成。然后,在項目演進的過程中不斷開發(fā)相應的功能,以滿足自己的需求。
如常見的日志功能,開始時可以手動進行相關的查詢。而后將其暴露到后臺服務應用中,再有針對性地對數(shù)據(jù)進行展示。多數(shù)組織對于這些工具的完善是抱著一種持續(xù)改進的態(tài)度來進行的。
設計能力的持續(xù)提升。如果出于人力、物力所限,設計的架構不夠合理,也沒關系——人的能力是在不斷提升的。若是有機會回到之前的場景,再慢慢思考這個問題,仍然有可能感覺當時的方案是最合適的。因此,對于方案而言,不存在最佳答案。建議大家在設計的時候為未來的改進留下一定的空間,以便于在未來隔離出這部分設計。
值得注意的是,關于架構相關的重要決定,還有一點很重要——延遲決策。如果架構上有多個可演進方向,無法做一個合適的決策,那么可以在條件更加充分的時候再做決策,而不是花費大量的時間盲目地修改架構,那樣只會造成資源浪費。
- Visual FoxPro 程序設計
- Python應用輕松入門
- 零基礎學MQL:基于EA的自動化交易編程
- 基于Swift語言的iOS App 商業(yè)實戰(zhàn)教程
- 3D少兒游戲編程(原書第2版)
- C語言課程設計
- 時空數(shù)據(jù)建模及其應用
- C指針原理揭秘:基于底層實現(xiàn)機制
- 官方 Scratch 3.0 編程趣味卡:讓孩子們愛上編程(全彩)
- 劍指大數(shù)據(jù):企業(yè)級電商數(shù)據(jù)倉庫項目實戰(zhàn)(精華版)
- Cinder:Begin Creative Coding
- Java 開發(fā)從入門到精通
- Java并發(fā)編程深度解析與實戰(zhàn)
- SQL優(yōu)化核心思想
- 軟件定義網(wǎng)絡:基于OpenFlow的SDN技術揭秘