詳細(xì)設(shè)計(jì)說明書模板:編碼前的最后一道關(guān)卡)
簡介面向軟件設(shè)計(jì)與開發(fā)人員這份資源提供一份可直接套用的軟件系統(tǒng)詳細(xì)設(shè)計(jì)說明書Word模板適合在項(xiàng)目詳設(shè)階段參考其結(jié)構(gòu)、快速撰寫規(guī)范文檔。模板完整覆蓋引言、設(shè)計(jì)概述、系統(tǒng)具體需求分析、總體方案確認(rèn)、系統(tǒng)具體設(shè)計(jì)等核心章節(jié)并對(duì)UI表達(dá)層、BLL業(yè)務(wù)邏輯層、DAL數(shù)據(jù)訪問層、Common類庫及實(shí)體類等分層設(shè)計(jì)給出明確描述位置同時(shí)包含版本歷史、修改記錄、目錄結(jié)構(gòu)系統(tǒng)功能模塊與界面設(shè)計(jì)部分還預(yù)留了子系統(tǒng)、模塊的擴(kuò)展占位便于團(tuán)隊(duì)按實(shí)際項(xiàng)目補(bǔ)充細(xì)節(jié)并評(píng)審追蹤。資源包僅1個(gè)doc文件大小169KB結(jié)構(gòu)清晰、可直接替換項(xiàng)目信息使用。目前已有227人學(xué)習(xí)下載適合需要統(tǒng)一詳細(xì)設(shè)計(jì)文檔格式或初次編寫詳設(shè)說明書的工程師參考。1. 軟件系統(tǒng)詳細(xì)設(shè)計(jì)說明書模板別把它當(dāng)文檔把它當(dāng)編碼前的最后一道關(guān)卡一份能用的軟件系統(tǒng)詳細(xì)設(shè)計(jì)說明書模板不是給評(píng)審擺樣子的格式文檔而是把需求文檔里的業(yè)務(wù)描述翻譯成程序員可以直接寫代碼的“施工圖”。我拆過不少系統(tǒng)見過太多項(xiàng)目在概要設(shè)計(jì)后直接進(jìn)編碼結(jié)果模塊接口各寫各的、數(shù)據(jù)庫字段對(duì)不上、三層架構(gòu)被寫成了大泥球最后全在聯(lián)調(diào)階段爆雷。這份 doc 模板的完整之處在于它把設(shè)計(jì)任務(wù)拆成了 7 個(gè)章節(jié)引言、設(shè)計(jì)概述、需求分析、總體方案確認(rèn)、系統(tǒng)具體設(shè)計(jì)、數(shù)據(jù)庫設(shè)計(jì)、信息編碼設(shè)計(jì)每一章都規(guī)定了該寫什么顆粒度的內(nèi)容。適合誰用適合正在做系統(tǒng)設(shè)計(jì)評(píng)審的技術(shù)負(fù)責(zé)人、被要求補(bǔ)詳細(xì)設(shè)計(jì)文檔的開發(fā)組長以及剛接手別人項(xiàng)目需要快速搞清架構(gòu)的維護(hù)者。它解決的是“設(shè)計(jì)文檔寫了等于沒寫”的普遍問題。2. 模板骨架與三層架構(gòu)為什么章節(jié)這么排UI/BLL/DAL 的邊界在哪2.1 七個(gè)標(biāo)準(zhǔn)章節(jié)的編排邏輯和閱讀對(duì)象這份模板的目錄順序不是隨便排的它遵循“從意圖到約束從全局到局部”的推導(dǎo)鏈條。第一章引言先交代編寫目的、背景、參考資料和術(shù)語作用是限定文檔的適用范圍防止讀者拿一份設(shè)計(jì)說明書去回答“為什么做這個(gè)系統(tǒng)”的問題——那是需求文檔的事。第二章設(shè)計(jì)概述給出任務(wù)和目的、需求概述、運(yùn)營環(huán)境、條件與限制這里要特別注意的是 2.1.3 條件與限制模板明確要求描述業(yè)務(wù)和技術(shù)方面的約束包括進(jìn)度和管理限制這一節(jié)是后期驗(yàn)收時(shí)扯皮的關(guān)鍵依據(jù)。真正體現(xiàn)模板功力的是從第三章開始的遞進(jìn)結(jié)構(gòu)。第三章做系統(tǒng)級(jí)需求分析強(qiáng)調(diào)對(duì)需求分析階段提出的企業(yè)需求做進(jìn)一步確認(rèn)并分析因情況變化帶來的需求變更——這是一個(gè)很多團(tuán)隊(duì)跳過的步驟直接導(dǎo)致設(shè)計(jì)基線漂移。第四章總體方案確認(rèn)專門解決系統(tǒng)總體結(jié)構(gòu)確認(rèn)和界面劃分我拆過幾個(gè)失敗案例都是因?yàn)閼?yīng)用系統(tǒng)與支撐系統(tǒng)的服務(wù)范圍沒劃清楚數(shù)據(jù)庫被多個(gè)子系統(tǒng)直接讀寫最后誰也動(dòng)不了表結(jié)構(gòu)。第五章進(jìn)入系統(tǒng)具體設(shè)計(jì)模板在這里給出了整個(gè)文檔最核心的內(nèi)容程序代碼架構(gòu)設(shè)計(jì)、子系統(tǒng)劃分、功能模塊設(shè)計(jì)、界面設(shè)計(jì)。第六章數(shù)據(jù)庫系統(tǒng)設(shè)計(jì)模板明確寫了可以單獨(dú)成冊(cè)對(duì)大型系統(tǒng)尤其如此。第七章信息編碼設(shè)計(jì)這個(gè)章節(jié)經(jīng)常被忽略但在做接口對(duì)接時(shí)沒有統(tǒng)一的編碼規(guī)范兩個(gè)系統(tǒng)傳同一個(gè)業(yè)務(wù)類型值一個(gè)用 01 一個(gè)用 1對(duì)接當(dāng)場翻車。從閱讀對(duì)象看第二、三章是給架構(gòu)師和技術(shù)評(píng)審看的確認(rèn)方向沒跑偏第五章是給編碼人員看的他們要照著模塊設(shè)計(jì)和算法描述寫實(shí)現(xiàn)第六章是給 DBA 看的第七章是給做接口開發(fā)和數(shù)據(jù)遷移的人看的。一份文檔要讓這幾類人都能快速找到自己要的內(nèi)容模板的章節(jié)作用就是這種“分角色檢索”的骨架。2.2 三層架構(gòu)怎么落到模板里UI、BLL、DAL 的職責(zé)邊界模板的 5.1 節(jié)直接指定了用三層架構(gòu)模型這是非常務(wù)實(shí)的選型。對(duì)絕大多數(shù)管理信息系統(tǒng)來說三層架構(gòu)不是技術(shù)時(shí)髦而是維護(hù)成本的底線UI 層只負(fù)責(zé)交互和簡單校驗(yàn)BLL 層承載所有邏輯判斷DAL 層只做數(shù)據(jù)訪問接口的裝配Entity 類和 Common 類庫作為橫向支撐。模板里有一句關(guān)鍵描述DAL 層只是數(shù)據(jù)庫的管理者但不是訪問者不直接與數(shù)據(jù)庫發(fā)生關(guān)聯(lián)。這句話的意思是 DAL 層暴露的是數(shù)據(jù)操作方法真正的數(shù)據(jù)庫連接和機(jī)械式數(shù)據(jù)交換被封裝在 Common 類庫的數(shù)據(jù)庫訪問類里。這種設(shè)計(jì)帶來的直接好處是替換數(shù)據(jù)庫供應(yīng)商時(shí)只需要改 Common 層DAL 層的接口簽名完全不用動(dòng)。壞處是層級(jí)多了以后調(diào)用鏈變長性能敏感的場景需要謹(jǐn)慎。模板里還規(guī)定了一個(gè)容易踩坑的細(xì)節(jié)數(shù)據(jù)庫中每個(gè)表都對(duì)應(yīng)一個(gè) BLL 類但 BLL 類不能直接調(diào)用其他表的 DAL 類而是 BLL 類之間互相調(diào)用。這是為了解耦但如果不控制好調(diào)用方向BLL 層之間會(huì)形成循環(huán)引用。各層職責(zé)可以用下表快速說清層/組件核心職責(zé)允許關(guān)聯(lián)的對(duì)象禁止事項(xiàng)UI 表現(xiàn)層交互、顯示、輸入有效性判斷、異常展示BLL、Entity、Common直接寫 SQL、直接操作 DALBLL 業(yè)務(wù)邏輯層所有邏輯判斷、功能實(shí)現(xiàn)、算法描述對(duì)應(yīng)代碼DAL、Entity、Common、其他 BLL關(guān)心 UI 層情況、跨表直調(diào) DALDAL 數(shù)據(jù)訪問層提供數(shù)據(jù)訪問接口、組合裝配數(shù)據(jù)庫操作語句Common、Entity包含邏輯判斷、直接與數(shù)據(jù)庫連接Common 類庫數(shù)據(jù)庫訪問類、鏈接字符串、數(shù)據(jù)庫引擎封裝數(shù)據(jù)庫本身承載業(yè)務(wù)邏輯Entity 實(shí)體類數(shù)據(jù)封裝表的字段對(duì)應(yīng)類的屬性無包含方法實(shí)現(xiàn)實(shí)際寫文檔時(shí)我習(xí)慣在 5.1 節(jié)放一張這樣的職責(zé)表再配一個(gè)簡單的項(xiàng)目結(jié)構(gòu)樹讓編碼人員第一眼就知道新代碼該往哪個(gè)項(xiàng)目里放。很多項(xiàng)目的分層混亂就是從這一節(jié)含糊開始的——模板給了準(zhǔn)確表述照著抄就行。2.3 從架構(gòu)描述到可執(zhí)行的檢查清單模板的 5.2 節(jié)要求做系統(tǒng)結(jié)構(gòu)設(shè)計(jì)及子系統(tǒng)劃分這里給出了一個(gè)實(shí)操性很強(qiáng)的方法按業(yè)務(wù)和功能把系統(tǒng)邏輯結(jié)構(gòu)劃分為若干子系統(tǒng)再按功能角度把子系統(tǒng)分解為功能模塊用層次圖描述總體結(jié)構(gòu)和模塊間的互相調(diào)用關(guān)系。我在用這份模板時(shí)會(huì)額外加一個(gè)檢查清單每個(gè)模塊必須有明確的輸入項(xiàng)頁面?zhèn)鲄ⅰ⒔涌谌雲(yún)?、輸出?xiàng)返回給 UI 的數(shù)據(jù)、處理過程描述偽碼或具體程序語言、參與的實(shí)體表。這四樣缺一樣編碼人員就會(huì)回頭問評(píng)審時(shí)就會(huì)被卡。3. 把用戶管理模塊寫成可直接編碼的規(guī)格從模塊描述到算法偽碼3.1 模塊描述和功能列表的正確寫法模板在 5.3.6.1 給出用戶管理模塊的完整示例這是全文最值得抄作業(yè)的部分。模塊描述是管理系統(tǒng)用戶包括添加用戶并賦予角色、修改用戶資料和角色、刪除用戶。主功能列了四條添加用戶、修改用戶、刪除用戶、列表和分頁。別小看這段描述它定義了模塊的邊界——登錄注銷被單獨(dú)拆到 5.3.6.4說明用戶管理和身份認(rèn)證是兩個(gè)模塊這避免了把登錄邏輯寫進(jìn)用戶管理里的常見錯(cuò)誤。每個(gè)子功能的描述格式模板給了一套固定模板輸入項(xiàng)、輸出項(xiàng)、算法描述。這套格式的價(jià)值在于把黑匣子打開。我常見的問題是開發(fā)人員只寫“實(shí)現(xiàn)添加用戶功能”評(píng)審?fù)耆珶o法判斷工作量和技術(shù)風(fēng)險(xiǎn)。用模板格式后添加用戶被拆成輸入用戶資料、選擇角色、加密密碼、驗(yàn)證必填項(xiàng)、驗(yàn)證用戶名是否存在、保存至用戶表、拆角色 ID 字符串、循環(huán)數(shù)組存角色關(guān)聯(lián)表、寫操作日志、返回成功失敗信息。拆到這一步代碼邏輯已經(jīng)浮現(xiàn)出來了。3.2 列表和分頁的算法描述為什么模板說“不用優(yōu)化分頁”模板對(duì)用戶列表分頁的描述非常有意思系統(tǒng)管理用戶數(shù)據(jù)量不大該功能使用頻率不高可以不用優(yōu)化分頁直接獲取用戶表所有記錄UI 層使用 gridview 控件調(diào)用 GetAllList() 綁定利用 gridview 自帶分頁功能。這句話透露了一個(gè)重要的設(shè)計(jì)判斷不是所有列表都要上真分頁。用戶管理表通常幾千條數(shù)據(jù)用控件自帶分頁完全夠用強(qiáng)行做存儲(chǔ)過程分頁反而增加維護(hù)成本。這個(gè)判斷應(yīng)該寫進(jìn)算法描述里因?yàn)樗窃O(shè)計(jì)決策的依據(jù)。模板要求算法描述主要說明 BLL 層代碼邏輯UI 層只做簡單輸入驗(yàn)證和界面顯示所以算法描述應(yīng)該落在方法調(diào)用粒度上。3.3 添加用戶模塊的關(guān)鍵算法MD5 加密與角色關(guān)聯(lián)模板在添加用戶里給出了加密方法MD5.Encrypt(string String, string Key)Key 用固定值。雖然是示例但作為安全上的注意點(diǎn)Key 實(shí)際使用時(shí)不能寫在代碼里明文固定至少應(yīng)該放到配置文件并做訪問控制。角色處理邏輯是模板的亮點(diǎn)先保存用戶到主表拿到用戶 ID再拆分角色 ID 字符串循環(huán)字符串?dāng)?shù)組逐條保存到角色關(guān)聯(lián)表。這個(gè)過程有一個(gè)事務(wù)性問題——如果第二步失敗用戶主表已經(jīng)寫入了。實(shí)際編碼時(shí)應(yīng)該用事務(wù)包住兩步或者在算法描述里補(bǔ)充回滾策略。模板的算法描述可以抽象成如下偽碼function AddUser(userInfo, roleIdString): // 1. 前端已校驗(yàn)必填項(xiàng)和兩次密碼一致BLL 層再次驗(yàn)證 if not validateRequired(userInfo): return failure(必填項(xiàng)缺失) // 2. 檢查用戶名唯一重復(fù)則直接返回失敗 if exists(System_admin_info, usernameuserInfo.username): return failure(用戶名已存在) // 3. MD5 加密密碼Key 從配置讀取 encryptedPassword MD5.Encrypt(userInfo.password, config.MD5Key) // 4. 保存用戶主表返回自增用戶 ID adminId DAL.System_admin_info.Add(userInfo with encryptedPassword) if adminId null: return failure(用戶保存失敗) // 5. 拆角色 ID 字符串逗號(hào)分隔循環(huán)寫角色關(guān)聯(lián)表 roleIds split(roleIdString, ,) for roleId in roleIds: DAL.Dict_admin_vs_roles.Add(adminId, roleId) // 6. 寫操作日志返回成功 logOperation(添加用戶, adminId) return success(添加用戶完畢)這段偽碼的邏輯說明前三步是前置校驗(yàn)和密碼處理不通過就短路返回避免無效數(shù)據(jù)進(jìn)入數(shù)據(jù)庫第四步返回自增 ID 是后續(xù)關(guān)聯(lián)表的外鍵必須獲取到第五步的循環(huán)是典型的主表 關(guān)聯(lián)表寫入模式最后寫日志保證操作可追溯。參數(shù)說明userInfo 是實(shí)體類對(duì)象包含姓名、密碼、聯(lián)系電話、E-mail、狀態(tài)等字段roleIdString 是前端勾選角色后拼接的 ID 字符串常用逗號(hào)分隔config.MD5Key 是加密密鑰必須與修改用戶模塊一致否則改密碼后舊密碼無法校驗(yàn)。3.4 修改和刪除用戶先刪關(guān)聯(lián)還是先刪主表模板里修改用戶算法有一個(gè)值得注意的順序先根據(jù)用戶 ID 刪除角色關(guān)聯(lián)表 Dict_admin_vs_roles 的記錄再重新分配角色。這是先刪后插模式實(shí)現(xiàn)簡單但有兩個(gè)坑。第一刪除和插入之間如果出錯(cuò)角色關(guān)聯(lián)數(shù)據(jù)會(huì)丟失第二沒有記錄變更前的角色無法做操作審計(jì)。我的做法是在算法描述里補(bǔ)充刪除關(guān)聯(lián)表前先查詢?cè)巧斜泶嫒肴罩静迦胄陆巧檬聞?wù)包裹。刪除用戶的算法順序剛好相反先刪角色關(guān)聯(lián)表再刪用戶主表。原因是外鍵約束存在時(shí)主表有子表引用無法直接刪除先刪子表再刪主表是標(biāo)準(zhǔn)姿勢。模板的算法描述里有一步值得借鑒無論刪除是否成功都要寫操作記錄日記。這比很多系統(tǒng)只在失敗時(shí)記日志要嚴(yán)謹(jǐn)——?jiǎng)h除成功也要知道是誰刪的。4. 數(shù)據(jù)庫設(shè)計(jì)與信息編碼模板里要求的六張關(guān)鍵設(shè)計(jì)維度4.1 從設(shè)計(jì)規(guī)定到信息模型數(shù)據(jù)庫章節(jié)的寫作順序模板第六章把數(shù)據(jù)庫設(shè)計(jì)拆成設(shè)計(jì)規(guī)定、信息模型設(shè)計(jì)、數(shù)據(jù)庫設(shè)計(jì)、數(shù)據(jù)字典四層其中數(shù)據(jù)庫設(shè)計(jì)又細(xì)分設(shè)計(jì)依據(jù)、種類及特點(diǎn)、邏輯結(jié)構(gòu)、物理結(jié)構(gòu)、安全。這個(gè)順序本質(zhì)是從業(yè)務(wù)需求推導(dǎo)數(shù)據(jù)結(jié)構(gòu)。很多團(tuán)隊(duì)寫數(shù)據(jù)庫設(shè)計(jì)就直接貼建表腳本跳過了信息模型設(shè)計(jì)結(jié)果表之間的關(guān)系沒人說得清后期加字段全靠猜。設(shè)計(jì)規(guī)定環(huán)節(jié)要回答數(shù)據(jù)被訪問的頻度和流量、最大數(shù)據(jù)存儲(chǔ)量、數(shù)據(jù)增長量、存儲(chǔ)時(shí)間。這些數(shù)字直接決定要不要做分表、歸檔和讀寫分離。信息模型設(shè)計(jì)階段確定實(shí)體或視圖、屬性、關(guān)鍵字和實(shí)體間聯(lián)系要用到 E-R 圖這是邏輯結(jié)構(gòu)設(shè)計(jì)的輸入。數(shù)據(jù)庫邏輯結(jié)構(gòu)設(shè)計(jì)是核心要把概念模式轉(zhuǎn)換為邏輯模式列出的每個(gè)數(shù)據(jù)項(xiàng)、記錄、文件的標(biāo)識(shí)、定義、長度及相互關(guān)系這是建表語句的依據(jù)顆粒度要到字段級(jí)別。4.2 數(shù)據(jù)字典與物理設(shè)計(jì)寫夠細(xì)節(jié)才能避免聯(lián)調(diào)翻車模板在 6.3.6 數(shù)據(jù)字典一節(jié)要求對(duì)數(shù)據(jù)項(xiàng)、記錄、系、文卷模式、子模式建立數(shù)據(jù)字典說明標(biāo)識(shí)符、同義名及有關(guān)信息。這是詳細(xì)設(shè)計(jì)說明書中最容易被水過去的部分。以用戶管理模塊涉及的兩張核心表為例數(shù)據(jù)字典至少應(yīng)該寫成這樣數(shù)據(jù)項(xiàng)標(biāo)識(shí)符同義名類型長度允許空約束/說明admin_id用戶IDint4否自增主鍵admin_name姓名nvarchar50否必填password用戶密碼varchar64否存儲(chǔ) MD5 密文telephone聯(lián)系電話varchar20是格式校驗(yàn)emailE-mailvarchar100是格式校驗(yàn)status狀態(tài)char1否0-禁用 1-啟用create_time創(chuàng)建時(shí)間datetime8否默認(rèn) getdate()物理結(jié)構(gòu)設(shè)計(jì)環(huán)節(jié)要求列出數(shù)據(jù)在內(nèi)存中的安排、外存設(shè)備及空間組織、訪問方式。這里需要寫清楚索引策略哪些字段建聚集索引、哪些建非聚集索引、數(shù)據(jù)文件與日志文件的存放位置、是否需要分區(qū)。以 System_admin_info 表為例管理端常按創(chuàng)建時(shí)間倒序查詢給 create_time 建非聚集索引是合理選擇而 Dict_admin_vs_roles 表最常用的查詢是按 admin_id 查角色那么以 admin_id 作為組合索引的前導(dǎo)列就是關(guān)鍵設(shè)計(jì)。4.3 信息編碼設(shè)計(jì)代碼結(jié)構(gòu)與代碼編制模板第七章信息編碼設(shè)計(jì)只有兩節(jié)代碼結(jié)構(gòu)設(shè)計(jì)和代碼編制。很多設(shè)計(jì)人員在這一章直接寫本系統(tǒng)無特殊編碼要求就略過了這是嚴(yán)重的偷懶。信息編碼是系統(tǒng)間接口協(xié)議的一部分用戶狀態(tài)是 0/1 還是啟用/禁用、角色 ID 是數(shù)字自增還是業(yè)務(wù)編碼這些不統(tǒng)一聯(lián)調(diào)時(shí)就會(huì)遇到 A 系統(tǒng)傳 01、B 系統(tǒng)按 1 解析的經(jīng)典事故。代碼結(jié)構(gòu)設(shè)計(jì)要確認(rèn)分類編碼總體方案比如用戶狀態(tài)碼采用一位數(shù)字代碼體系第 1 位表示大類0-業(yè)務(wù)狀態(tài) 1-系統(tǒng)狀態(tài)第 2 位表示具體狀態(tài)代碼編制則按結(jié)構(gòu)逐條列出編碼值與含義并說明新增編碼的審批流程。5. 避坑用這套模板寫詳細(xì)設(shè)計(jì)的 5 個(gè)常見翻車點(diǎn)5.1 把需求描述當(dāng)成詳細(xì)設(shè)計(jì)現(xiàn)象、原因、解決現(xiàn)象模塊設(shè)計(jì)章節(jié)里寫滿了系統(tǒng)應(yīng)支持用戶管理管理員可以添加用戶并分配角色和需求文檔幾乎一字不差編碼人員看完還是不知道該建幾張表、寫幾個(gè)方法。原因?qū)懳臋n的人把詳細(xì)設(shè)計(jì)說明書當(dāng)成了需求復(fù)述沒有做從業(yè)務(wù)描述到技術(shù)方案的翻譯。解決嚴(yán)格按照模板的輸入項(xiàng)、輸出項(xiàng)、算法描述三段式來寫每個(gè)功能至少列出所有輸入字段、返回信息、涉及的表、調(diào)用的 BLL/DAL 方法名寫不出來就說明設(shè)計(jì)沒到位。5.2 流程圖只畫主干異常分支全被省略現(xiàn)象模塊設(shè)計(jì)的流程圖只有一條順利路徑比如添加用戶就是輸入資料→驗(yàn)證→保存→成功四個(gè)框完全沒有重復(fù)用戶名、數(shù)據(jù)庫異常、角色拆分失敗這些分支。原因畫圖的人圖省事或者根本沒推演過異常場景。解決參考模板用戶管理模塊的文字流程描述把驗(yàn)證用戶名是否存在→是否成功→返回失敗信息這條分支顯式地畫出來并同步在算法描述里寫明每個(gè)失敗分支的返回值和處理動(dòng)作。好的設(shè)計(jì)文檔異常分支的字?jǐn)?shù)應(yīng)該比正常路徑多。5.3 算法描述停留在業(yè)務(wù)敘述沒到方法調(diào)用粒度現(xiàn)象處理/算法描述寫的是保存用戶并分配角色沒有說明調(diào)用哪個(gè)類的哪個(gè)方法、參數(shù)是什么、返回值如何處理。原因?qū)懳臋n的人沒把設(shè)計(jì)當(dāng)作編碼前的最終抽象還停留在業(yè)務(wù)層面。解決按模板的示例格式把算法描述寫到具體方法調(diào)用粒度例如分拆角色 ID 字符串并循環(huán)字符串?dāng)?shù)組信息保存至表 Dict_admin_vs_rolesExamSys.BLL.Dict_admin_vs_roles Add(ExamSys.Model.Dict_admin_vs_roles model)。寫清楚這個(gè)方法簽名編碼人員不需要再猜。5.4 BLL 層互相調(diào)用導(dǎo)致循環(huán)依賴現(xiàn)象BLL 類之間互相調(diào)用后項(xiàng)目編譯時(shí)提示程序集循環(huán)引用或者雖然能編譯但每次改動(dòng)一個(gè)業(yè)務(wù)方法關(guān)聯(lián)模塊的測試全掛。原因模板雖然規(guī)定 BLL 類之間可以互相調(diào)用但沒限定調(diào)用方向團(tuán)隊(duì)就隨意互相引用最終 A 調(diào) B、B 調(diào) C、C 又調(diào) A。解決在系統(tǒng)結(jié)構(gòu)設(shè)計(jì)章節(jié)額外加一節(jié)BLL 調(diào)用規(guī)則規(guī)定調(diào)用只能向下或平級(jí)依賴禁止反向調(diào)用如果兩個(gè) BLL 確實(shí)需要互相協(xié)作把公共邏輯下沉到 Common 類庫或引入服務(wù)接口層。5.5 數(shù)據(jù)庫設(shè)計(jì)脫離訪問頻度索引亂建現(xiàn)象上線后用戶列表查詢極慢排查發(fā)現(xiàn)開發(fā)人員給所有經(jīng)常查詢的字段都建了索引結(jié)果寫操作頻繁的表因?yàn)樗饕S護(hù)開銷反而性能更差。原因數(shù)據(jù)庫設(shè)計(jì)章節(jié)的設(shè)計(jì)依據(jù)沒有寫清楚數(shù)據(jù)訪問頻度和流量開發(fā)只能憑感覺建索引。解決在 6.3.1 設(shè)計(jì)依據(jù)里明確寫出高頻查詢路徑和預(yù)期并發(fā)量然后按訪問模式設(shè)計(jì)索引。只讀為主的表可以適當(dāng)多建索引高頻寫入的表要控制索引數(shù)量。寫進(jìn)設(shè)計(jì)文檔里后端開發(fā)就有了統(tǒng)一的索引決策依據(jù)。6. 把模板改造成團(tuán)隊(duì)可復(fù)用的設(shè)計(jì)基線三個(gè)具體落地技巧6.1 在模板里加一頁設(shè)計(jì)決策記錄表這份模板的標(biāo)準(zhǔn)章節(jié)里沒有專門的決策記錄位置但實(shí)際項(xiàng)目中每一個(gè)設(shè)計(jì)選擇背后都有備選方案和取舍原因。我的習(xí)慣是在第五章系統(tǒng)具體設(shè)計(jì)開頭插入一張?jiān)O(shè)計(jì)決策表記錄決策編號(hào)、決策內(nèi)容、備選方案、選擇理由、影響范圍。三個(gè)典型例子分頁方案選 gridview 自帶分頁而不是存儲(chǔ)過程分頁理由是數(shù)據(jù)量小、開發(fā)效率優(yōu)先密碼加密選固定 Key 的 MD5理由是歷史系統(tǒng)兼容新系統(tǒng)應(yīng)升級(jí)到哈希加鹽角色關(guān)聯(lián)表刪除采用先刪后插理由是邏輯簡單但需補(bǔ)事務(wù)保護(hù)。這張表的直接價(jià)值是三個(gè)月后有人問當(dāng)時(shí)為什么要這么設(shè)計(jì)不用考古聊天記錄。6.2 把算法描述統(tǒng)一成方法調(diào)用鏈格式模板的算法描述允許用偽碼或具體程序語言我發(fā)現(xiàn)最實(shí)用的格式是方法調(diào)用鏈。比如刪除用戶模塊寫成UI 點(diǎn)擊刪除按鈕 → 傳 admin_id 到 BLL DeleteAdmin(int admin_id) → 先調(diào) BLL.Dict_admin_vs_roles.DeleteByAdminID(admin_id) → 再調(diào) DAL.System_admin_info.Delete(admin_id) → 返回 bool 結(jié)果 → UI 按結(jié)果顯示刷新。這個(gè)鏈條上的每個(gè)環(huán)節(jié)都有明確的類名和方法簽名新人照著寫代碼不需要?jiǎng)幽X子猜。從那以后我每次評(píng)審設(shè)計(jì)文檔第一件事就是檢查算法描述里能不能提取出完整的方法調(diào)用鏈提取不出來就退回重寫。6.3 用字段級(jí)數(shù)據(jù)字典替代近似的建表腳本模板要求的數(shù)據(jù)字典很容易被敷衍成見建表腳本但建表腳本只有字段定義沒有同義名和設(shè)計(jì)意圖后期不同模塊對(duì)同一個(gè)字段的理解經(jīng)常出現(xiàn)偏差。我在模板基礎(chǔ)上把數(shù)據(jù)字典的表格擴(kuò)展成五列數(shù)據(jù)項(xiàng)標(biāo)識(shí)符、同義名、類型長度、允許空、約束與說明并要求約束與說明這一列必須寫業(yè)務(wù)含義比如 status 字段的 0-禁用 1-啟用要寫清楚是全局枚舉還是模塊本地枚舉。這樣一來設(shè)計(jì)文檔里的字典就成了接口對(duì)賬的依據(jù)聯(lián)調(diào)時(shí)不用來回問狀態(tài)到底有哪幾個(gè)值。這份模板最實(shí)用的地方不是它的排版而是它強(qiáng)制你把設(shè)計(jì)想法落到輸入、輸出、算法、表結(jié)構(gòu)、編碼規(guī)則這些可以驗(yàn)證的顆粒度上。把它改造成團(tuán)隊(duì)自己的基線版本再加一張決策記錄表往后每個(gè)項(xiàng)目都能少開幾輪需求澄清會(huì)。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取