if 我是前端團隊 Leader,怎麼制定前端協作規範?在掘金目前已經突破740個?了, 謝謝大家的支援,這篇文章是前者延展。繼續介紹我在前端團隊管理方面的思考和探索。
軟體工程中有一個軟體設計階段,通俗的講就是在開工之前將能確定的確定下來,把該考慮的考慮了。這相比在開發階段發現問題,解決的成本要低很多。
如果按照教科書上的定義,軟體設計就是是一個將需求轉變為軟體陳述(表達)的過程。一般有概要設計(或者初步設計, Preliminary design)和詳細設計(Detail design). 概要設計將需求轉換成資料和軟體框架,而詳細設計將框架逐步求精細化為具體的資料結構和軟體的演算法表達。本文講述的是前端專案的概要設計。
相比後端開發, 對於前端,’軟體設計‘很少被提及,也有可能是一直以來前端的工作都比較'簡單',所以比較粗放。一般給了原型和介面文件就直接開幹了。但是隨著前端開發者的工作越來越複雜,或者專案/團隊的規模變大,我們越來越需要在編碼之前進行合理的設計。
作為前端入門Leader, 最近面臨了一些問題: 比如專案分工問題、專案維護缺乏文件問題, 讓我開始重視軟體設計階段. 就目前看來,做好前端概要設計,至少有以下好處:
- 事前. 設計文件是開發的藍圖,後續開發可以按照這個文件逐步展開。良好的設計可以保證開發沿著正常軌道邁進。
- 我們在設計階段會進一步梳理業務流程,加深對業務流程的理解,甚至可以找出業務流程中的不合理的東西。
- 模組拆分。這個階段我們會識別各個模組之間邊界和重疊,將重疊的(共享的)部分抽離出來。另外模組是基本的開發工作單元,也是我們團隊分工和時間評估的基礎。
- 考察關鍵的技術點。提出多種備選方案,充分考慮各種風險, 選擇符合實際需求的方案
- 事後. 設計文件對事後的軟體維護、功能新增,有很大的幫助
下面開始介紹,前端在軟體設計階段應該考慮東西,或者說前端的概要設計文件
裡面應該包含哪些東西. 當然這些只是一些初步的想法,隨著後面深入實踐後,本文會持續更新迭代.
文章大綱
系列文章
這方面我的經驗實踐比較少, 也沒有在大廠待過,所以本文只是我的一些思考和嘗試, 可能不太現實。如果你或你的團隊有這方面的更好的實踐,歡迎分享給我。感激?
關鍵業務流程的梳理
開發任何一個產品之前,首先要確保的是對業務流程的理解,否則就會出現南轅北轍的情況。
在現實專案中發生過多次這類情況:專案到達測試階段,測試人員才發現應用的業務實現和產品定義不一樣,或者業務流程不合理。 這其實是一種很低階的失誤,改動的成本可能很高,甚至會讓你的所有工作白乾。
管理比較成熟的公司會有很多手段來規避這種失誤。
比如定義明確需求文件,這方面可以模仿一些標準/規範(Spec)的寫作方法,嚴格定義一些關鍵字,避免模稜兩可的描述;
另外可以通過各種宣貫會議,將相關人員聚集在一起,統一匯入需求。在這些會議中可以進行頭腦風暴,優化或細化需求的定義、發現缺陷和風險,分析可行性等等。通過不斷溝通,成員之間可以分享交叉知識,確保對業務一致理解.
因此,我覺得前端在設計階段也應該像後端一樣,用流程圖或者時序圖這類工具,將關鍵業務流程描述清楚. 尤其是涉及到前後端, 跨系統/跨頁面/跨終端之間的業務互動的場景.
舉個例子,比如我們在做一個’掃碼登入‘功能。我們可以將跨終端的業務梳理出來:
從上面的業務梳理中我們可以識別出業務物件的基本行為和狀態. 例如二維碼的狀態轉換圖:
當然, 簡單的增刪查改花篇幅去闡述沒有意義。我們只關注應用關鍵的業務流程.
總之,業務流程的梳理,可以加深我們對業務的理解,是後續設計步驟和開發的基礎.
關鍵技術點
描述應用採用的或者涉及到關鍵技術/演算法, 也可以認為是技術選型.
比如典型的有視訊直播應用,涉及到的各種直播方案:
- RTMP 協議
- RTP協議
- HLS 協議
- flv.js
- WebRTC協議
- 等等
在開啟一個專案之前, 我們需要對專案涉及到的關鍵技術點進行調研和測試,最好多找幾個替代方案,橫向地比較它們的優勢和劣勢。選擇符合專案或團隊自己情況的方案. 如果時間充足, 可以寫一些Demo,實地踩一下坑.
如果有多個備選方案,最後要甄選出推薦方案,並說明選擇的原因和考慮。
提前做好技術的調研和選型,確定可行性,不至於開發處於被動的境地.
關於如何進行技術選型,我在if 我是前端團隊 Leader,怎麼制定前端協作規範?進行了簡單的討論,可以參考一下.
模組設計
現代前端一般都使用元件化思維進行開發,這時候我們的應用其實就是一顆由不同粒度的元件複合起來的元件樹,這顆元件樹最終會體現到專案的目錄結構上。 在設計階段我們可以根據產品原型或UI設計稿,識別出各種頁面和元件。
正常的應用,我們可以分三個層級進行拆分:
入口層
稍微複雜一點的應用可能有多個入口,這些入口呈現的頁面可能差異很大. 下面是一個常見的劃分方法:
- 按子系統劃分: 比如前臺和後臺。
- 按角色劃分:比如管理員、普通使用者
- 按入口劃分:比如移動端、桌面端等等
頁面層
下一步就是識別各種頁面,這些頁面即對應到我們的前端路由配置規則. 以下面簡單的應用為例:
關於模組的劃分,我建議使用思維導圖進行組織。模組劃分這個環節,你可以召集團隊的其他成員開個會議,一起進行頭腦風暴。大家參照著產品原型,識別出各種模組或元件的邊界和交集, 討論怎麼設計頁面的資料流、元件的介面等等, 這樣可以利用集體智慧,讓模組拆分更加合理,另外可以促進團隊成員提前熟悉專案的結構。
所以說軟體設計不是架構師或設計人員一個人的事,應該鼓勵大家一起參與,設計文件是整個軟體團隊的產出, 是團隊的知識沉澱。
上面的應用通過頁面層劃分後,結果大概如下:
在這個階段我們會確定以下內容:
- 頁面以及路由設計, 確定頁面之間的層級關係
- 頁面之間互動流程、資料傳遞
關於路由設計,可以遵循一些規範,筆者比較推薦Restful URL規範, 這篇文章寫得也不錯.
路由之間的資料傳遞一般有以下幾種方式:
- 少量資料:可以通過路由變數(例如
/posts/:id
)或者查詢字串形式傳遞. 還有如果你使用的是基於History API的前端路由模式,可以使用History的state物件來儲存一些狀態(最大640k) - 大量資料:可以通過全域性變數,或者狀態管理器的機制進行儲存, 不管這種儲存在記憶體的方式,一旦頁面重新整理就會丟失。所以也可以考慮儲存在本地快取中, 例如LocalStorage
元件層
Ok,再往下拆分,不過要量力而行。對於一個非常複雜的專案來說,可能有成千上百個元件,而且這些元件在未來可能會不斷變化,在設計階段考慮這些拆分可能需要花費很多時間,而且收益並不明顯。
那麼需要怎麼把握粒度呢?其實元件層設計階段的主要目的是找出重複的、或者結構類似的元件,將它們抽取出來統一的設計,在多個頁面進行復用. 並不是把所有的元件都列舉出來。
我在React元件設計實踐總結02 - 元件的組織這篇文章中,專門介紹React元件如何進行組織和拆分。其中提出了以下集中模式:
- 容器元件和展示元件分離。或者說分離檢視和邏輯, 業務元件和傻瓜元件. 純邏輯的東西放在Hooks中,使用起來會更加方便
- 純元件和非純元件. 可以認為純元件完全依賴外部輸入
- 有狀態元件和無狀態元件
- 佈局元件和內容元件
- 統一設計同一型別元件的介面. 比如表單元件應該保持介面統一
還是上面的示例應用,申報頁面有非常多的表單項,而且經常變動,另外你會發現它和預覽頁面的結構是差不多的,而且後面可能會有桌面端頁面。
經過討論,我們決定採用配置檔案的方式來動態渲染表單頁和預覽頁。實現一套配置控制移動端申請表單、桌面端申請表單、移動端預覽、桌面端預覽頁面。
類似上面這種應用場景,前期的元件層設計就很有必要了。
分工
將模組拆分清楚後,我們就可以針對這些模組進行合理的分工和時間評估。基本上有三個步驟:
通過上面的步驟,我們識別出來了各種模組,接著我們要確定下來這些模組之間的依賴關係,這些依賴關係影響它們是否要作為一個整體進行實現。最後再根據業務的優先順序或依賴關係決定這些模組簇的實現優先順序。
Ok, 現在可以將這些模組簇按照優先順序排序, 加上評估時間(人天),整理成一個清單。 如果你們使用看板來進行專案管理, 可以將它們作為一個任務單元,貼到看板中.
1. Foo 功能
- c 2d
- d 1d
- f 3d
2. Bar 功能
- e 1d
- h 0.5d
3. Baz 功能
- g 1d
4. Fu 功能
- a 4d
- b 1d
總計人天: 13.5
複製程式碼
任務的分工有很多策略, 例如:
- 橫向劃分
- 公共元件 vs 業務元件(對接業務)
- 自上而下 vs 自下而上(指的是元件樹)
- 垂直劃分: 按照獨立的垂直模組分工
狀態設計
前端元件化伴隨而來的是各種資料驅動
或資料流驅動
的開發模式。這種模式下,前端應用可以總結為這樣一個等式:
view = f(state)
複製程式碼
也就是說檢視是資料或者資料流的對映. 可見狀態管理對現代前端開發的重要性。
狀態的設計和後端物件模型設計差不多。你需要根據業務和頁面渲染要求抽象出各種物件模型,以及縷清物件模型之間的關係。這個階段可能需要和後端緊密結合,才能確定出合理的物件結構。
當然狀態的設計還跟你選擇的狀態管理方案也有關係, 不同狀態管理器方案體現的思想差異較大:如果你選擇Redux,那麼應用的狀態就是一顆物件樹;如果你選擇Mobx,應用的狀態可能由多個模型物件組成,更接近傳統的OOP模式。
如果採用OOP設計方法,可以繪製UML
圖,視覺化表現物件的結構和關係:
我在React元件設計實踐總結05 - 狀態管理這篇文章花了很多篇幅來介紹各種狀態管理器的思想和開發模式, 所以這裡就不展開了:
Redux 狀態設計:
Mobx 狀態設計:
介面設計
如果前端團隊在介面設計方面有主導權, 或者使用BFF架構(服務於前端的後端),在設計階段我們需要對各類介面進行設計。
不過一般主導權都掌握在後端手裡,因為前端對業務的關心程度較低,後端一般會綜合考慮各端的介面需求、資料庫儲存效率、可維護性等多個方面來設計介面, 這時候前端就是介面的使用者,我們有責任來驗證後端介面是否符合需求.
我在if 我是前端團隊 Leader,怎麼制定前端協作規範?已經提及了各種介面規範. 這裡不予贅述。
版本規劃
通過上面的步驟,我們基本已經瞭解我們需要做什麼、需要花多久。接下來,
應該制定一個版本計劃,對於一個大專案可以拆分為多個里程碑, 估計版本釋出的時間. 加不加班就看你了,作為Leader要綜合考慮各種影響因素,實事求是合理地安排版本釋出計劃。
這個釋出計劃可能還需要經過PM和專案經理稽核, 作為前端專案,開發計劃通常還依賴於後端團隊.
這個版本計劃中會包含這些內容:
- 版本號
- 釋出時間
- 包含的主要模組
驗證
驗證,或者稱為’測試指導‘。 除了測試團隊提供的測試用例,從開發(白盒)的角度還需要注意哪些東西?
產品或者測試可能只會從業務的層次考慮應用的執行,我們需要從研發的角度,充分考慮各種異常情況、效能瓶頸、進行風險評估. 闡明風險的應對方案等待.
這些情況也可以反饋給測試團隊,以完善測試的用例.
專案要求和目標
一些需求是要提前確定下來的,對於前端來說,比較典型的就是瀏覽器相容性要求。你可不要等到專案上線後,才跟我提使用者要求相容IE6!
這些專案要求可能會影響我們的開發成本、選型、測試和其他因素的評估。基本上,對於一個前端專案來說,這些要求是要提前問清楚的:
- 瀏覽器相容性
- 執行環境. 例如作業系統、小程式等等
- 時間點
- 效能指標要求. 例如首屏指標、資料量指標
文件索引
前端專案開發可能會關聯很多文件,這些文件是分散的,在設計文件中最好把它們聚合起來,方便查閱和引用. 例如:
- 需求文件
- DEMO, UI設計稿
- 測試用例
- 介面文件
- UI設計規範文件
- 前端規範文件
- ...
構建說明
如果你的專案需要設計構建流程,也可以在設計文件中簡單提及。
例如如何編譯和執行? 如何測試和除錯? 如何部署或釋出? 程式碼如何組織?開發工作流、編碼約定等等
新成員通過這些說明可以快速上手開發.
持續迭代
設計文件不是一次性的,它應該跟隨專案不斷的迭代,不然就失去了文件的意義。
模板
最後,規範一些設計文件的格式和內容
# XXX 概要設計文件
## 背景
填寫專案的背景, 或者開發或重構的目的/出發點.
## 關鍵業務流程
可以放置關鍵的業務流程圖、狀態圖、物件圖等等. 梳理關鍵的業務流程
## 關鍵技術描述
可選, 描述專案中使用到的關鍵技術、演算法、選型結論等等
## 模組拆分
- 入口
- 頁面路由
- 元件設計
可以使用思維導圖描述
## 狀態設計
描述應用涉及的關鍵領域物件, 比如外形、行為和關係. 如果是OOP方式,可以使用UML描述
## 介面設計
可選,如題
## 專案要求和目標
專案目標、執行環境、相容性要求、效能指標等等
## 驗證
可選, 風險評估、異常情況考慮、特殊測試規則、測試指導等等
## 分工和版本計劃
可選, 可以在單獨文件或者看板中維護
## 構建說明
可選, 專案組織、構建、測試說明
## 文件索引
相關文件的索引和連結
## 參考資料
文件中索引頁的外部參考資料
## CHANGELOG
列出本文件修改的歷史紀錄。必須指明修改的內容、日期以及修改人
複製程式碼
很多開發人員都不喜歡寫文件,包括我以前也是這樣的。我們會找各種藉口:’時間緊張,沒時間做設計‘、’用來寫設計文件的時間,我的開發早就做完了‘。
這些想法顯然是不正確的,給我的啟示是我們要根據團隊情況而定,不要求設計文件有多麼詳盡,在時間緊張的時候可以粗略一點。等時間充裕再回顧補充也是可以接受的; 或者如果專案劃分為多個週期進行開發,我們也可以在每個週期開始時進行詳細的設計。
總結
文章差不多寫完了,看到了知乎@張明雲現代軟體開發中,詳細設計這一步要如何來做?下面的一個回答:
和我上文所介紹基本吻合。一個軟體’概要‘設計文件基本就包含這幾大塊。
本文完。