<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          DDD 到底是銀彈還是垃圾

          共 4225字,需瀏覽 9分鐘

           ·

          2021-11-01 18:30

          每過(guò)一段時(shí)間,就會(huì)有人跳出來(lái)批判 DDD,這東西到底是垃圾還是銀彈?

          在某某公司干活的時(shí)候,有一批人聲稱要用 DDD 改造老舊系統(tǒng),徹底解決核心流程規(guī)?;螅?xiàng)目難以維護(hù)的問(wèn)題。之前某篇文章里的這張圖,就是在用 DDD 做項(xiàng)目重構(gòu)之前的爛攤子:

          24d8298792422fc18a5280ddd6216499.webp

          大家都很聰明,聰明到最后沒(méi)人知道這新需求到底該往哪里寫了。架構(gòu)師們聚在一起學(xué)習(xí) DDD 精神,產(chǎn)出學(xué)習(xí)報(bào)告,大半年過(guò)去,終于出了一些成果,有些子項(xiàng)目完成了用 DDD 進(jìn)行的重構(gòu),年底可以拿來(lái)在酒會(huì)上邀功了,這下我們跟上了業(yè)界業(yè)務(wù)開發(fā)的主流方法論,可喜可賀,可喜可賀啊。

          年末的時(shí)候部門內(nèi)匿名提問(wèn)的小紙條卻向架構(gòu)師們發(fā)直球:“為什么用了 DDD 以后,代碼更難懂了?”,當(dāng)時(shí)引得各位 DDD 推手尷尬無(wú)比,只能搪塞過(guò)去。

          所以你覺得我是要批判么?那倒不是。

          在某某司工作期間,到離職前,我把市面上所有 DDD 相關(guān)的書全部看了一遍。對(duì)其理論體系進(jìn)行了完整的了解,可以說(shuō)這套理論還是有些用處的,DDD 的理論誕生時(shí)間比較早,微服務(wù)的趨勢(shì)是后來(lái)才爆發(fā)的。但微服務(wù)剛開始沒(méi)有明確的拆分指導(dǎo),人們發(fā)現(xiàn) DDD 里的 bounded context 好像看著正好和服務(wù)的粒度是可以做個(gè)對(duì)應(yīng)的,DDD 就成為了很多公司做業(yè)務(wù)的絕對(duì)主流方法論。

          雖然很多技術(shù)人員不愛聽,但是技術(shù)優(yōu)劣和商業(yè)成敗其實(shí)沒(méi)什么必然的聯(lián)系。同樣的,方法論的對(duì)錯(cuò)和項(xiàng)目的成功與否也沒(méi)有必然的關(guān)系。很多大公司做業(yè)務(wù)的人出來(lái)講他們的技術(shù)方法論,這些人可能連自己的項(xiàng)目為啥成功都不一定知道,你指望能對(duì)你的場(chǎng)景產(chǎn)生直接幫助那可能是想多了。只是當(dāng)聽個(gè)樂(lè),得個(gè)借鑒那可能還沒(méi)什么問(wèn)題。真的當(dāng)金科玉律去執(zhí)行,那撞一頭包也正常。

          DDD 和其它的工程方法論一樣,沒(méi)有辦法證偽。放眼望去,純粹堆砌人肉電池,不用 DDD 的項(xiàng)目也那么多成功的,大家的屁股還是在跟著公司的市值跑,哪家公司市值漲到中國(guó)第一了,那他們的技術(shù)就牛逼,這叫看市值決定價(jià)值觀。如果一家公司靠 996 成功了,那 996 就是商業(yè)致勝的法寶,不學(xué)你就落后了。屁股可以決定腦袋嘛。

          不過(guò)作為一個(gè)矜持的技術(shù)人員,我們?cè)谂蟹椒ㄕ摰臅r(shí)候,還是應(yīng)該要先對(duì)敵人有一些了解。

          所以這一篇,我就簡(jiǎn)單帶你們看看 DDD 里那些鬼名詞都是什么意思。

          戰(zhàn)術(shù)設(shè)計(jì)與戰(zhàn)略設(shè)計(jì)

          整個(gè) DDD 的方法論可以劃分為兩個(gè)大模塊,戰(zhàn)術(shù)設(shè)計(jì)、戰(zhàn)略設(shè)計(jì)。這個(gè)你顧名思義,戰(zhàn)術(shù)是小,戰(zhàn)略是大。

          • 戰(zhàn)術(shù)設(shè)計(jì)指的就是單模塊級(jí)的設(shè)計(jì),基本都是純技術(shù)范疇的東西,只DDD 中給代碼命名和模塊設(shè)計(jì)給出了一些指導(dǎo)方法
          • 戰(zhàn)略設(shè)計(jì)指的是大項(xiàng)目的模塊拆分,這個(gè)和一線程序員關(guān)系不大,主要是公司內(nèi)怎么在 bu 之間切蛋糕,bu 內(nèi)怎么在 team 之間分贓

          現(xiàn)在很多校招程序員可能或多或少都會(huì)碰到一些 OOP 方面的面試題,比如三大特性五大原則之類的,這些原則是設(shè)計(jì)項(xiàng)目的時(shí)候可以參考的原則, DDD 的戰(zhàn)術(shù)設(shè)計(jì)就是在單模塊上的各種命名規(guī)則和設(shè)計(jì)方法。只不過(guò) OOP 這些原則的發(fā)明人(嚴(yán)格的說(shuō)應(yīng)該是匯總?cè)?是 uncle bob,就是 《clean code》,《clean architecture》 的作者,這位白胡子爺爺大概率和 DDD 社區(qū)是尿不到一個(gè)壺里的,所以 《clean architecture》 這本書里只字未提 DDD。

          公司的業(yè)務(wù)要怎么分派給不同的 bu(部門)去完成,這個(gè)一般是公司 CTO 或者 GM 要做的事情,部門內(nèi)的項(xiàng)目要怎么分,哪些組做哪些事情。這是戰(zhàn)略設(shè)計(jì)的范疇。DDD 聲稱戰(zhàn)略設(shè)計(jì)也是要有方法的。這部分也是很多程序員認(rèn)為最沒(méi)用的一部分,我們后面來(lái)批判一下這些程序員。

          戰(zhàn)術(shù)設(shè)計(jì)

          戰(zhàn)術(shù)設(shè)計(jì)是純技術(shù)范疇的東西,最讓人頭痛的就是里面的名詞。

          貧血模式和充血模式:DDD 推薦你用充血模式寫代碼,也就是按 OOP 的方式去做抽象,然后把行為掛在對(duì)象上,而不是以純過(guò)程式 的方法去寫代碼。所謂的充血,就是對(duì)象本身有很多關(guān)聯(lián)的行為,而不只是一個(gè)單純的數(shù)據(jù)庫(kù)的表的字段映射。DDD 聲稱的充血模式的優(yōu)勢(shì)是,大部分的行為被封裝到了對(duì)象內(nèi)部,這樣我們?cè)陂喿x流程代碼的時(shí)候,是一目了然的,直接能看到 step 1,step 2,step 3。但實(shí)際即使我們不用 OOP 來(lái)組織行為,一樣可以把不同的業(yè)務(wù) step 做好封裝和復(fù)用。有些公司的服務(wù)粒度拆的特別細(xì),比如只有 5000-10000 行代碼,在 DDD 里聲稱的充血模式的優(yōu)勢(shì)沒(méi)有那么明顯。

          值對(duì)象和實(shí)體:這個(gè)也挺離譜的,值對(duì)象就是純粹的數(shù)值、文本類型,比如:

          type?person?struct?{
          ??age?int
          ??name?string
          }

          就是值對(duì)象,如果我們給這個(gè) person 加一個(gè) id,讓它能表示 person 的唯一性了;

          type?person?struct?{
          ??id??int
          ??age?int
          ??name?string
          }

          那它就是實(shí)體了。

          這兩個(gè)概念只是給我們?nèi)粘S玫膶?duì)象們進(jìn)行了一個(gè)簡(jiǎn)單的分類,沒(méi)什么大用處。

          聚合根:DDD 里所謂的聚合根是事務(wù)粒度的 entity,也就是說(shuō),如果我們對(duì) db 進(jìn)行存取,那么我們就需要有一個(gè)聚合根,如果在一個(gè)事務(wù)里需要操作多張表,那么就需要給多張表關(guān)聯(lián)一個(gè)單獨(dú)的聚合根。

          d937cd7ef98d71c4333b82fed002016a.webp

          聚合根可以由一個(gè) entity 組成,也可以由多個(gè) entity 組成,就是你完成一個(gè) db 事務(wù)的時(shí)候有多少關(guān)聯(lián)的對(duì)象 ,那可能就有多少在同一個(gè)聚合根下面的 entity。

          六邊形架構(gòu):這個(gè)所謂的六邊形架構(gòu),就是除了業(yè)務(wù)以外的所有外部變化都抽象成 adapter interface 做適配。如果你稍微理解一點(diǎn)點(diǎn)點(diǎn)依賴反轉(zhuǎn),那應(yīng)該知道怎么樣去做這種抽象。如果你一點(diǎn)都不了解,那我建議你去看看 go-micro 的代碼。如果看不懂,建議還是盡早轉(zhuǎn)行吧~

          7eaaaa869d8f85f56a9f5d8109674931.webp

          六邊形架構(gòu)這東西主要是名字實(shí)在起的太奇怪,在 《clean architecture》那本書里,uncle bob 也給過(guò)一張圖:

          4a1aacf34da190215227f63cfb71cd2a.webp

          《evolutionary architecture》這本書出自造詞大本營(yíng) thoughtworks 的員工之手,里面有一個(gè) plugin architecture,就是有些人特別喜歡說(shuō)的插件化架構(gòu):

          2eb978c618b4aade71a0051d94fa02dd.webp

          Repo Pattern:DDD 理論認(rèn)為我們業(yè)務(wù)項(xiàng)目的存儲(chǔ)這一層是可能經(jīng)常變化的,所以就專門存儲(chǔ)層的 interface 設(shè)計(jì)單獨(dú)拿出來(lái),稱為 Repo Pattern,這東西實(shí)在沒(méi)啥可說(shuō)的,find,getlist,save,你只要有一點(diǎn)點(diǎn) orm 經(jīng)驗(yàn),里面有啥接口應(yīng)該自己都可以默寫出來(lái)。

          事實(shí)是在 2021 年,我們的存儲(chǔ)系統(tǒng)基本是不太可能做切換的了,即使切換,那些新興的社區(qū)存儲(chǔ)系統(tǒng)也會(huì)支持 MySQL 協(xié)議,基礎(chǔ)設(shè)施想要侵入代碼,那簡(jiǎn)單是大逆不道啊。

          領(lǐng)域事件:其實(shí)就是做上下游解耦的 kafka message,我們用 domain event 顯得會(huì)更洋氣一些。

          領(lǐng)域服務(wù):Domain service,顧名思義,你認(rèn)為是自己部門或者組內(nèi)的局部 api gateway 也是可以的。

          綜上,如果你是在大公司一線工作了兩三年的程序員,上面這些東西應(yīng)該馬上就能理解,沒(méi)有啥值得說(shuō)的。如果是為了去架構(gòu)師大會(huì)上秀一秀,你總得包裝一下讓自己顯得沒(méi)那么土吧?

          戰(zhàn)略設(shè)計(jì)

          Domain:領(lǐng)域,你們公司是干啥的,你都不知道嗎?

          Core Domain:你們公司的賣貨的,那賣貨就是你們與其它競(jìng)爭(zhēng)對(duì)手的關(guān)鍵競(jìng)爭(zhēng)環(huán)節(jié)。這就是核心域,就是核心業(yè)務(wù),為啥聰明人都往核心業(yè)務(wù)擠?核心業(yè)務(wù)的湯也比邊緣業(yè)務(wù)的飯好啊。

          SubDomain:你們公司的賣貨的,但是用戶沒(méi)法付錢,那也沒(méi)法干,支付就是子領(lǐng)域。

          Supporting Domain:你們公司是賣貨的,但是客戶想看一些指標(biāo),你總得有系統(tǒng)能支持吧?可能就是些寫寫 SQL 的系統(tǒng)。支持域。

          Generic Domain:你管你們公司干什么呢?員工的在職離職,工資發(fā)放總得有系統(tǒng)能支持吧,這些就是通用域。

          除了第一個(gè) Domain ,其余四個(gè) domain 重要性逐級(jí)遞減,遞減的意思是,如果公司要裁員,那是從下面往上面裁。

          前面我說(shuō)有些程序員覺得 DDD 戰(zhàn)略設(shè)計(jì)沒(méi)用,你連自己所在的組,從事的工作職責(zé)對(duì)于公司來(lái)說(shuō)重不重要都不清楚,那被裁的時(shí)候也別哭哦。

          統(tǒng)一語(yǔ)言:這個(gè)就更好理解了,比如跳水這個(gè)詞,你說(shuō)跳水的時(shí)候指的是這個(gè):

          d3e6860c2b3cdf1b4b7b3064ebe1444a.webp

          而你同事說(shuō)跳水的時(shí)候指的是這個(gè):

          15ebc94c91ac382c6eeeec5aba5ce96c.webp

          這里你們聊的是工作,那說(shuō)明你們一定不是在同一個(gè)上下文里工作,可能你們倆一個(gè)在體育賽事部門,另一個(gè)可能是在金融部門, DDD 認(rèn)為可以用統(tǒng)一語(yǔ)言來(lái)進(jìn)行領(lǐng)域劃分工作。劃分后在同一個(gè)上下文內(nèi),同一個(gè)名詞大家說(shuō)出來(lái)意思一致。這就是 Bounded Context, ?ain。

          既然拆分了,如果我們還在同一個(gè) domain 內(nèi),那完成業(yè)務(wù)流程是需要協(xié)作的,這個(gè)不同 Context 的協(xié)作方式就叫 Context Maps 或者 Integration Type。

          名詞很惡心,但具體的方法就兩種,兩個(gè)微服務(wù)要么通過(guò) RPC 通信,要么通過(guò) MQ 通信。

          如果通過(guò) RPC 通信,那 callee 一般是 caller 的爹,很多時(shí)候 callee 掛了是要影響 caller 的(當(dāng)然也有熔斷之類的方法避免一起死)。

          通過(guò)通過(guò) MQ 通信,那上游一般是下游的爹,因?yàn)樯嫌我粋€(gè)重構(gòu),下游們可能就都炸了,最終一致都是屁話,多少公司的最終一致都是靠人肉修的。

          這種爹和兒子的關(guān)系就是 Conformist。如果爹能多考慮一下兒子的需求,那就是 Customer-Supplier 關(guān)系,畢竟顧客名義上還是上帝。如果跨系統(tǒng)有一些需要共享的定義,比如公司里的業(yè)務(wù)分類,可能大家都要從某個(gè)系統(tǒng)的 PHP 文件里解析出來(lái)在自己的系統(tǒng)里去用,那這時(shí)候可能得去使用別人的代碼,這種叫 Shared-Kernel,Kernel 一改,大家一起死。

          最后,有時(shí)候我們可以用一個(gè)叫 ACL 的東西攔住上游的一些修改對(duì)我們的業(yè)務(wù)邏輯侵入:

          防腐層:Anti-Corruption-Layer,就是我要把外部系統(tǒng)的變化攔截在對(duì)接層,不要讓別人的屎甩到我身上。

          講到這里,基本的概念我們已經(jīng)都過(guò)一遍了,你要說(shuō) DDD 一點(diǎn)用處都沒(méi)有,那我也是不同意的,至少看完了這些書,我知道去哪里能賺到更多的錢了。

          額外再說(shuō)一句,DDD 的書寫的都不怎么樣。

          瀏覽 66
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美性受XXXX | 麻豆AV三级电影 | 青青草免费在线观看 | 手机看片自拍 | 亚洲成人网站在线播放 |