議驅(qū)動(dòng)(一))
協(xié)議驅(qū)動(dòng)協(xié)議驅(qū)動(dòng)設(shè)計(jì)圍繞三大核心原則落地適配輕量化、高迭代的開(kāi)發(fā)場(chǎng)景。三大核心思想具體如下接口即協(xié)議獨(dú)立閉環(huán)每一個(gè)API接口對(duì)應(yīng)一套獨(dú)立協(xié)議各協(xié)議擁有專(zhuān)屬的入?yún)⒛P?、出參模型、業(yè)務(wù)處理類(lèi)業(yè)務(wù)邏輯完全閉環(huán)。協(xié)議扁平對(duì)等無(wú)相互依賴(lài)所有協(xié)議處于同一層級(jí)、地位平等無(wú)上下級(jí)、無(wú)優(yōu)先級(jí)區(qū)分禁止協(xié)議之間相互調(diào)用、耦合依賴(lài)。協(xié)議用完即棄迭代換新協(xié)議適配當(dāng)前業(yè)務(wù)場(chǎng)景即可一旦出現(xiàn)場(chǎng)景不適配、大規(guī)模不兼容迭代不改造舊協(xié)議直接全新創(chuàng)建協(xié)議舊協(xié)議保留、按需廢棄。極度適配中小團(tuán)隊(duì)敏捷迭代實(shí)現(xiàn)主動(dòng)擁抱需求變化、核心業(yè)務(wù)保持恒定無(wú)需復(fù)雜 DDD 領(lǐng)域建模、無(wú)需高強(qiáng)度代碼評(píng)審適配工期緊、需求多變、無(wú)詳細(xì)前置設(shè)計(jì)的開(kāi)發(fā)場(chǎng)景用輕量化架構(gòu)解決傳統(tǒng)分層架構(gòu)職責(zé)混亂、代碼失控的頑疾。哪里有敏捷開(kāi)發(fā)只不過(guò)是把工期緊任務(wù)重并且沒(méi)有詳細(xì)設(shè)計(jì)加上邊做邊想甚至是先做出來(lái)再說(shuō)這種開(kāi)發(fā)流程美化一番好讓程序猿同學(xué)有種非常高大上的錯(cuò)覺(jué)從而心甘情愿地多加班而已業(yè)務(wù)背景在遙遠(yuǎn)的sevlet年代一個(gè)sevlet將業(yè)務(wù)邏輯處理、數(shù)據(jù)持久化包干。后來(lái)拆分成‘模型 - 視圖 - 控制器’三層又添加并細(xì)分‘Controller - Service - Dao’Controller負(fù)責(zé)請(qǐng)求接收、參數(shù)校驗(yàn)、路由調(diào)度與響應(yīng)返回Service專(zhuān)注核心業(yè)務(wù)邏輯的編排與實(shí)現(xiàn)Dao負(fù)責(zé)數(shù)據(jù)庫(kù)交互、數(shù)據(jù)持久化操作。這套分層架構(gòu)雖實(shí)現(xiàn)了基礎(chǔ)職責(zé)拆分但在中小團(tuán)隊(duì)、高頻迭代的業(yè)務(wù)場(chǎng)景中暴露了無(wú)法規(guī)避的短板Service層代碼臃腫膨脹隨著業(yè)務(wù)迭代迭代大量業(yè)務(wù)邏輯堆砌在Service類(lèi)中多人協(xié)作開(kāi)發(fā)時(shí)極易出現(xiàn)代碼沖突、分支合并問(wèn)題文件體量持續(xù)失控。層級(jí)邊界混亂隔離失效受開(kāi)發(fā)人員能力、規(guī)范落地不到位影響層級(jí)職責(zé)經(jīng)常被打破部分開(kāi)發(fā)者會(huì)將業(yè)務(wù)邏輯寫(xiě)入Controller層甚至直接在控制層通過(guò)Dao、JDBC操作數(shù)據(jù)庫(kù)即便項(xiàng)目已定義標(biāo)準(zhǔn)化入?yún)⒛P腿源嬖谕ㄟ^(guò)request.getParameter()手動(dòng)獲取參數(shù)的不規(guī)范操作。架構(gòu)適配性有限大廠可通過(guò)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)DDD、嚴(yán)格代碼評(píng)審、規(guī)范化研發(fā)流程保障代碼質(zhì)量、延長(zhǎng)代碼生命周期。但絕大多數(shù)小微企業(yè)無(wú)專(zhuān)職代碼審核人員研發(fā)人員能力參差不齊傳統(tǒng)分層架構(gòu)的規(guī)范難以落地代碼冗余、耦合、混亂問(wèn)題愈發(fā)嚴(yán)重維護(hù)成本極高。協(xié)議驅(qū)動(dòng)設(shè)計(jì)正是針對(duì)中小團(tuán)隊(duì)快速迭代、規(guī)范薄弱、業(yè)務(wù)多變的場(chǎng)景提出的輕量化破局方案。協(xié)議驅(qū)動(dòng)核心思想深度解析1. 最小顆粒度協(xié)議拆分業(yè)務(wù)完全閉環(huán)協(xié)議對(duì)應(yīng)的API接口需拆分至最小業(yè)務(wù)顆粒以業(yè)務(wù)場(chǎng)景、功能單一為拆分依據(jù)即便同為Banner圖查詢(xún)接口若A、B兩處返回?cái)?shù)據(jù)格式不同需拆分為兩個(gè)獨(dú)立協(xié)議新增、編輯類(lèi)操作若業(yè)務(wù)邏輯、數(shù)據(jù)校驗(yàn)規(guī)則不同可獨(dú)立拆分協(xié)議堅(jiān)決杜絕“大一統(tǒng)接口”禁止一個(gè)接口承載頁(yè)面全部數(shù)據(jù)返回、多場(chǎng)景復(fù)合業(yè)務(wù)處理。同時(shí)每個(gè)協(xié)議的入?yún)⒛P?、出參模型、業(yè)務(wù)處理類(lèi)專(zhuān)屬獨(dú)享僅服務(wù)于當(dāng)前協(xié)議業(yè)務(wù)物理層面將臃腫的Service大類(lèi)按單一業(yè)務(wù)維度拆分為多個(gè)獨(dú)立協(xié)議處理類(lèi)從根源解決代碼膨脹問(wèn)題單一協(xié)議的代碼修改、迭代、Bug修復(fù)完全不會(huì)影響其他協(xié)議實(shí)現(xiàn)業(yè)務(wù)邏輯物理隔離問(wèn)題定位精準(zhǔn)高效所有與某一接口相關(guān)的問(wèn)題僅局限于對(duì)應(yīng)協(xié)議的代碼范圍內(nèi)大幅降低排查成本。協(xié)議扁平解耦無(wú)狀態(tài)無(wú)依賴(lài)所有協(xié)議保持扁平、對(duì)等、無(wú)狀態(tài)特性不存在層級(jí)關(guān)系、優(yōu)先級(jí)差異和相互依賴(lài)調(diào)用。該設(shè)計(jì)的核心目的是極致解耦、強(qiáng)化單一職責(zé)即使刪除某一個(gè)協(xié)議的全部代碼也不會(huì)對(duì)系統(tǒng)內(nèi)其他協(xié)議、其他業(yè)務(wù)邏輯造成任何影響徹底規(guī)避跨業(yè)務(wù)耦合風(fēng)險(xiǎn)。用完即棄契合開(kāi)閉原則當(dāng)業(yè)務(wù)出現(xiàn)大規(guī)模迭代新舊接口邏輯不兼容、無(wú)法通過(guò)簡(jiǎn)單兼容改造適配時(shí)無(wú)需修改舊協(xié)議代碼直接全新開(kāi)發(fā)一套新協(xié)議即可。新舊協(xié)議并行存在、各司其職完美契合軟件設(shè)計(jì)的開(kāi)閉原則對(duì)修改關(guān)閉、對(duì)擴(kuò)展開(kāi)放。客戶(hù)端未升級(jí)場(chǎng)景持續(xù)調(diào)用舊協(xié)議保留原有業(yè)務(wù)邏輯客戶(hù)端已升級(jí)場(chǎng)景切換調(diào)用新協(xié)議執(zhí)行全新業(yè)務(wù)邏輯。堅(jiān)決杜絕在同一個(gè)接口中堆砌大量版本兼容代碼避免代碼冗余、邏輯混亂。僅需特殊校驗(yàn)是否存在“客戶(hù)端未升級(jí)但必須使用新協(xié)議”的特殊場(chǎng)景評(píng)估場(chǎng)景合理性與落地必要性即可。代碼復(fù)用與數(shù)據(jù)持久化落地方案協(xié)議扁平獨(dú)立、互不調(diào)用的設(shè)計(jì)可規(guī)避耦合問(wèn)題但也衍生出核心問(wèn)題多協(xié)議存在公共邏輯、重復(fù)代碼以及統(tǒng)一數(shù)據(jù)持久化如何處理核心解決方案為邏輯下沉、分層復(fù)用。協(xié)議驅(qū)動(dòng)不強(qiáng)制限定 Model、Service、Dao 的固定架構(gòu)可與行業(yè)主流的數(shù)據(jù)驅(qū)動(dòng)模式混用一張數(shù)據(jù)庫(kù)表對(duì)應(yīng)一套獨(dú)立的表模型Model、Dao操作類(lèi)、Mapper映射文件、通用Service類(lèi)。其中表對(duì)應(yīng)通用Service類(lèi)主要承擔(dān)兩大核心職責(zé)實(shí)現(xiàn)代碼復(fù)用與能力下沉通用數(shù)據(jù)操作封裝封裝單表/關(guān)聯(lián)子表的通用增刪改查能力包含分頁(yè)查詢(xún)、新增、修改等基礎(chǔ)數(shù)據(jù)庫(kù)操作與具體業(yè)務(wù)場(chǎng)景解耦核心公共業(yè)務(wù)封裝沉淀多協(xié)議通用的核心業(yè)務(wù)邏輯如緩存管理、發(fā)送消息等避免重復(fù)編碼。通過(guò)該方式協(xié)議處理類(lèi)僅專(zhuān)注于自身專(zhuān)屬業(yè)務(wù)邏輯通用數(shù)據(jù)庫(kù)操作、公共邏輯全部下沉至基礎(chǔ)Service層既保留協(xié)議的獨(dú)立性又解決了代碼復(fù)用問(wèn)題。靈活適配原則規(guī)范服務(wù)于業(yè)務(wù)協(xié)議驅(qū)動(dòng)的核心目標(biāo)是簡(jiǎn)化開(kāi)發(fā)、降低維護(hù)成本而非固化刻板規(guī)則。若少量多個(gè)協(xié)議存在完全一致的入?yún)ⅰ⒊鰠⒛P颓覙I(yè)務(wù)處理邏輯高度重合允許直接復(fù)用模型與核心代碼無(wú)需強(qiáng)行拆分冗余代碼。所有架構(gòu)規(guī)范均為業(yè)務(wù)服務(wù)在不破壞核心解耦、獨(dú)立閉環(huán)的前提下可根據(jù)實(shí)際場(chǎng)景靈活適配兼顧架構(gòu)規(guī)范性與開(kāi)發(fā)高效性。對(duì)應(yīng)實(shí)戰(zhàn)項(xiàng)目地址https://github.com/bugCats/cat-bcdt包括網(wǎng)址導(dǎo)航SQL版本管理SQL計(jì)劃任務(wù)Mysql代理數(shù)據(jù)庫(kù)賬號(hào)權(quán)限申請(qǐng)審批代碼生成web端日志查閱團(tuán)隊(duì)日?qǐng)?bào)禪道、Jenkins、Gitea、Gitlab消息集成等案例分析案例1最小顆粒協(xié)議拆分對(duì)應(yīng)獨(dú)立閉環(huán)思想商城首頁(yè)需要展示兩種Banner廣告首頁(yè)輪播Banner、彈窗推薦Banner。二者數(shù)據(jù)庫(kù)字段一致但前端渲染出參格式不同輪播Banner需返回圖片地址、跳轉(zhuǎn)鏈接、排序權(quán)重彈窗Banner僅需返回圖片地址、展示時(shí)長(zhǎng)。傳統(tǒng)寫(xiě)法容易合并為一個(gè) getBanner() 大一統(tǒng)接口冗余字段多、迭代牽一發(fā)而動(dòng)全身。協(xié)議驅(qū)動(dòng)模式下直接拆分為 BannerHomeProtocol、BannerPopupProtocol 兩個(gè)獨(dú)立協(xié)議各自配備專(zhuān)屬入?yún)?、出參和處理?lèi)后續(xù)僅修改彈窗Banner邏輯時(shí)完全不會(huì)影響首頁(yè)輪播業(yè)務(wù)。案例2協(xié)議扁平無(wú)依賴(lài)對(duì)應(yīng)對(duì)等解耦思想用戶(hù)中心包含「用戶(hù)登錄」「用戶(hù)信息查詢(xún)」「用戶(hù)手機(jī)號(hào)修改」三個(gè)接口對(duì)應(yīng)三套獨(dú)立協(xié)議。傳統(tǒng)Service架構(gòu)下三類(lèi)用戶(hù)業(yè)務(wù)邏輯會(huì)堆砌在同一個(gè)UserService中修改手機(jī)號(hào)邏輯極易誤影響登錄、查詢(xún)功能多人開(kāi)發(fā)也容易產(chǎn)生代碼沖突。而協(xié)議驅(qū)動(dòng)模式下三個(gè)業(yè)務(wù)對(duì)應(yīng)三個(gè)扁平獨(dú)立協(xié)議互不依賴(lài)、互不調(diào)用。物理刪除用戶(hù)手機(jī)號(hào)修改協(xié)議的全部代碼登錄、用戶(hù)查詢(xún)功能完全不受影響真正實(shí)現(xiàn)協(xié)議之間徹底解耦、零耦合風(fēng)險(xiǎn)。案例3協(xié)議用完即棄、版本迭代換新對(duì)應(yīng)開(kāi)閉原則思想商城訂單接口迭代場(chǎng)景V1版本訂單接口僅支持普通實(shí)物訂單下單邏輯簡(jiǎn)單、參數(shù)較少后續(xù)業(yè)務(wù)升級(jí)新增預(yù)售訂單、分期支付訂單且新增大量校驗(yàn)字段、履約邏輯新舊邏輯完全不兼容。傳統(tǒng)開(kāi)發(fā)寫(xiě)法在原有訂單接口中新增大量if/else兼容判斷堆砌V1、V2兩套邏輯代碼臃腫晦澀后續(xù)迭代極易出Bug維護(hù)難度極大。協(xié)議驅(qū)動(dòng)寫(xiě)法不改動(dòng)原有V1訂單協(xié)議代碼全新開(kāi)發(fā)一套V2訂單協(xié)議。老版本APP調(diào)用舊協(xié)議保持原有下單邏輯穩(wěn)定新版本APP調(diào)用新協(xié)議適配全新訂單業(yè)務(wù)。無(wú)需兼容舊邏輯、不污染老代碼完美實(shí)現(xiàn)用完即扔、迭代擴(kuò)展。案例4公共邏輯下沉復(fù)用對(duì)應(yīng)分層落地方案系統(tǒng)中「商品列表查詢(xún)」「商品詳情查詢(xún)」兩個(gè)獨(dú)立協(xié)議均需要查詢(xún)商品基礎(chǔ)數(shù)據(jù)、統(tǒng)一封裝商品狀態(tài)、過(guò)濾下架商品。按照協(xié)議規(guī)范兩個(gè)協(xié)議代碼獨(dú)立、不能相互調(diào)用。此時(shí)將商品基礎(chǔ)查詢(xún)、狀態(tài)過(guò)濾通用邏輯下沉至商品基礎(chǔ)Service層兩個(gè)協(xié)議分別調(diào)用Service公共能力自身僅保留各自專(zhuān)屬業(yè)務(wù)邏輯列表協(xié)議專(zhuān)注分頁(yè)、排序、精簡(jiǎn)字段返回詳情協(xié)議專(zhuān)注參數(shù)校驗(yàn)、完整數(shù)據(jù)組裝。既保證協(xié)議獨(dú)立解耦又避免大量重復(fù)代碼。案例5規(guī)范靈活適配、避免過(guò)度設(shè)計(jì)對(duì)應(yīng)靈活適配原則系統(tǒng)內(nèi)「獲取用戶(hù)基礎(chǔ)信息」「獲取用戶(hù)實(shí)名認(rèn)證信息」兩個(gè)簡(jiǎn)單接口入?yún)⒕鶠橛脩?hù)ID、出參均為基礎(chǔ)用戶(hù)字段無(wú)特殊差異化邏輯。無(wú)需強(qiáng)行拆分兩套模型、兩套處理類(lèi)可直接復(fù)用同一套出入?yún)⒛P秃凸蔡幚磉壿嫛?協(xié)議驅(qū)動(dòng)核心是解耦、提效而非機(jī)械刻板拆分在不破壞核心架構(gòu)思想的前提下可靈活復(fù)用代碼規(guī)避過(guò)度設(shè)計(jì)。