\1. 【強(qiáng)制】存儲方案和底層數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)獲得評審一致通過,并沉淀成為文檔。
說明:有缺陷的底層數(shù)據(jù)結(jié)構(gòu)容易導(dǎo)致系統(tǒng)風(fēng)險(xiǎn)上升,可擴(kuò)展性下降,重構(gòu)成本也會因歷史數(shù)據(jù)遷移和系統(tǒng)平滑過渡而陡然增加,所以,存儲方案和數(shù)據(jù)結(jié)構(gòu)需要認(rèn)真地進(jìn)行設(shè)計(jì)和評審,生產(chǎn)環(huán)境提交執(zhí)行后,需要進(jìn)行 double check。
正例:評審內(nèi)容包括存儲介質(zhì)選型、表結(jié)構(gòu)設(shè)計(jì)能否滿足技術(shù)方案、存取性能和存儲空間能否滿足業(yè)務(wù)發(fā)展、表或字段之間的辯證關(guān)系、字段名稱、字段類型、索引等;數(shù)據(jù)結(jié)構(gòu)變更(如在原有表中新增字段)也需要進(jìn)行評審?fù)ㄟ^后上線。
\2. 【強(qiáng)制】在需求分析階段,如果與系統(tǒng)交互的 User 超過一類并且相關(guān)的 User Case 超過 5 個(gè),使用用例圖來表達(dá)更加清晰的結(jié)構(gòu)化需求。
\3. 【強(qiáng)制】如果某個(gè)業(yè)務(wù)對象的狀態(tài)超過 3 個(gè),使用狀態(tài)圖來表達(dá)并且明確狀態(tài)變化的各個(gè)觸發(fā)條件。
說明:狀態(tài)圖的核心是對象狀態(tài),首先明確對象有多少種狀態(tài),然后明確兩兩狀態(tài)之間是否存在直接轉(zhuǎn)換關(guān)系,再明確觸發(fā)狀態(tài)轉(zhuǎn)換的條件是什么。
正例:淘寶訂單狀態(tài)有已下單、待付款、已付款、待發(fā)貨、已發(fā)貨、已收貨等。比如已下單與已收貨這兩種狀態(tài)之間是不可能有直接轉(zhuǎn)換關(guān)系的。
\4. 【強(qiáng)制】如果系統(tǒng)中某個(gè)功能的調(diào)用鏈路上的涉及對象超過 3 個(gè),使用時(shí)序圖來表達(dá)并且明確各調(diào)用環(huán)節(jié)的輸入與輸出。
說明:時(shí)序圖反映了一系列對象間的交互與協(xié)作關(guān)系,清晰立體地反映系統(tǒng)的調(diào)用縱深鏈路。
\5. 【強(qiáng)制】如果系統(tǒng)中模型類超過 5 個(gè),并且存在復(fù)雜的依賴關(guān)系,使用類圖來表達(dá)并且明確類之間的關(guān)系。
說明:類圖像建筑領(lǐng)域的施工圖,如果搭平房,可能不需要,但如果建造螞蟻 Z 空間大樓,肯定需要詳細(xì)的施工圖。
\6. 【強(qiáng)制】如果系統(tǒng)中超過 2 個(gè)對象之間存在協(xié)作關(guān)系,并且需要表示復(fù)雜的處理流程,使用活動圖來表示。
說明:活動圖是流程圖的擴(kuò)展,增加了能夠體現(xiàn)協(xié)作關(guān)系的對象泳道,支持表示并發(fā)等。
\7. 【推薦】系統(tǒng)架構(gòu)設(shè)計(jì)時(shí)明確以下目標(biāo):
? 確定系統(tǒng)邊界。確定系統(tǒng)在技術(shù)層面上的做與不做。
? 確定系統(tǒng)內(nèi)模塊之間的關(guān)系。確定模塊之間的依賴關(guān)系及模塊的宏觀輸入與輸出。
? 確定指導(dǎo)后續(xù)設(shè)計(jì)與演化的原則。使后續(xù)的子系統(tǒng)或模塊設(shè)計(jì)在一個(gè)既定的框架內(nèi)和技術(shù)方向上繼續(xù)演化。
? 確定非功能性需求。非功能性需求是指安全性、可用性、可擴(kuò)展性等。
\8. 【推薦】需求分析與系統(tǒng)設(shè)計(jì)在考慮主干功能的同時(shí),需要充分評估異常流程與業(yè)務(wù)邊界。
反例:用戶在淘寶付款過程中,銀行扣款成功,發(fā)送給用戶扣款成功短信,但是支付寶入款時(shí)由于斷網(wǎng)演練產(chǎn)生異常,淘寶訂單頁面依然顯示未付款,導(dǎo)致用戶投訴。
\9. 【推薦】類在設(shè)計(jì)與實(shí)現(xiàn)時(shí)要符合單一原則。
說明:單一原則最易理解卻是最難實(shí)現(xiàn)的一條規(guī)則,隨著系統(tǒng)演進(jìn),很多時(shí)候,忘記了類設(shè)計(jì)的初衷。
10.【推薦】謹(jǐn)慎使用繼承的方式來進(jìn)行擴(kuò)展,優(yōu)先使用聚合/組合的方式來實(shí)現(xiàn)。
說明:不得已使用繼承的話,必須符合里氏代換原則,此原則說父類能夠出現(xiàn)的地方子類一定能夠出現(xiàn),比如,“把錢交出來”,錢的子類美元、歐元、人民幣等都可以出現(xiàn)。
11.【推薦】系統(tǒng)設(shè)計(jì)階段,根據(jù)依賴倒置原則,盡量依賴抽象類與接口,有利于擴(kuò)展與維護(hù)。
說明:低層次模塊依賴于高層次模塊的抽象,方便系統(tǒng)間的解耦。
12.【推薦】系統(tǒng)設(shè)計(jì)階段,注意對擴(kuò)展開放,對修改閉合。
說明:極端情況下,交付的代碼是不可修改的,同一業(yè)務(wù)域內(nèi)的需求變化,通過模塊或類的擴(kuò)展來實(shí)現(xiàn)。
13.【推薦】系統(tǒng)設(shè)計(jì)階段,共性業(yè)務(wù)或公共行為抽取出來公共模塊、公共配置、公共類、公共方法等,在系統(tǒng)中不出現(xiàn)重復(fù)代碼的情況,即 DRY 原則(Don't Repeat Yourself)。
說明:隨著代碼的重復(fù)次數(shù)不斷增加,維護(hù)成本指數(shù)級上升。隨意復(fù)制和粘貼代碼,必然會導(dǎo)致代碼的重復(fù),在維護(hù)代碼時(shí),需要修改所有的副本,容易遺漏。必要時(shí)抽取共性方法,或者抽象公共類,甚至是組件化。
正例:一個(gè)類中有多個(gè) public 方法,都需要進(jìn)行數(shù)行相同的參數(shù)校驗(yàn)操作,這個(gè)時(shí)候請抽?。簆rivate boolean checkParam(DTO dto) {...}
14.【推薦】避免如下誤解:敏捷開發(fā) = 講故事 + 編碼 + 發(fā)布。
說明:敏捷開發(fā)是快速交付迭代可用的系統(tǒng),省略多余的設(shè)計(jì)方案,摒棄傳統(tǒng)的審批流程,但核心關(guān)鍵點(diǎn)上的必要設(shè)計(jì)和文檔沉淀是需要的。
反例:某團(tuán)隊(duì)為了業(yè)務(wù)快速發(fā)展,敏捷成了產(chǎn)品經(jīng)理催進(jìn)度的借口,系統(tǒng)中均是勉強(qiáng)能運(yùn)行但像面條一樣的代碼,可維護(hù)性和可擴(kuò)展性極差,一年之后,不得不進(jìn)行大規(guī)模重構(gòu),得不償失。
15.【參考】設(shè)計(jì)文檔的作用是明確需求、理順邏輯、后期維護(hù),次要目的用于指導(dǎo)編碼。
說明:避免為了設(shè)計(jì)而設(shè)計(jì),系統(tǒng)設(shè)計(jì)文檔有助于后期的系統(tǒng)維護(hù)和重構(gòu),所以設(shè)計(jì)結(jié)果需要進(jìn)行分類歸檔保存。
\16. 【參考】可擴(kuò)展性的本質(zhì)是找到系統(tǒng)的變化點(diǎn),并隔離變化點(diǎn)。
說明:世間眾多設(shè)計(jì)模式其實(shí)就是一種設(shè)計(jì)模式即隔離變化點(diǎn)的模式。
正例:極致擴(kuò)展性的標(biāo)志,就是需求的新增,不會在原有代碼交付物上進(jìn)行任何形式的修改。
17.【參考】設(shè)計(jì)的本質(zhì)就是識別和表達(dá)系統(tǒng)難點(diǎn)。
說明:識別和表達(dá)完全是兩回事,很多人錯誤地認(rèn)為識別到系統(tǒng)難點(diǎn)在哪里,表達(dá)只是自然而然的事情,但是大家在設(shè)計(jì)評審中經(jīng)常出現(xiàn)語焉不詳,甚至是詞不達(dá)意的情況。準(zhǔn)確地表達(dá)系統(tǒng)難點(diǎn)需要具備如下能力: 表達(dá)規(guī)則和表達(dá)工具的熟練性。抽象思維和總結(jié)能力的局限性?;A(chǔ)知識體系的完備性。深入淺出的生動表達(dá)力。
18.【參考】代碼即文檔的觀點(diǎn)是錯誤的,清晰的代碼只是文檔的某個(gè)片斷,而不是全部。
說明:代碼的深度調(diào)用,模塊層面上的依賴關(guān)系網(wǎng),業(yè)務(wù)場景邏輯,非功能性需求等問題是需要相應(yīng)的文檔來完整地呈現(xiàn)的。
19.【參考】在做無障礙產(chǎn)品設(shè)計(jì)時(shí),需要考慮到:
? 所有可交互的控件元素必須能被 tab 鍵聚焦,并且焦點(diǎn)順序需符合自然操作邏輯。
? 用于登錄校驗(yàn)和請求攔截的驗(yàn)證碼均需提供圖形驗(yàn)證以外的其它方式。
? 自定義的控件類型需明確交互方式。
正例:用戶登錄場景中,輸入框的按鈕都需要考慮 tab 鍵聚焦,符合自然邏輯的操作順序如下,“輸入用戶名,輸入密碼,輸入驗(yàn)證碼,點(diǎn)擊登錄”,其中驗(yàn)證碼實(shí)現(xiàn)語音驗(yàn)證方式。如果有自定義標(biāo)簽實(shí)現(xiàn)的控件設(shè)置控件類型可使用 role 屬性。
更多建議: