主頁 > 軟體設計 > 一文揭秘DDD到底解決了什么問題

一文揭秘DDD到底解決了什么問題

2023-05-14 09:32:36 軟體設計

DDD作為架構設計思想幫助微服務控制規模復雜度,那它是怎么做到的呢?

 

一、架構設計是為了解決系統復雜度

談到架構,相信每個技術人員都是耳熟能詳,但如果深入探討一下,“為何要做架構設計?”或者“架構設計目的是什么?”類似的問題,大部分人可能從來沒有思考過,或者即使有思考,也沒有太明確可信的答案,

 

1.1 架構設計的誤區

1.1.1 每個系統都要做架構設計/公司流程要求有架構設計

知其然更要知其所以然,不能僅僅因為其他公司都在做架構設計而盲目跟從,而應該深入理解架構設計的目的和必要性,根據實際需求進行合理的設計,如果架構師或設計師只是為了找點事做而進行架構設計,不僅會浪費時間和人力,還會拖慢整體開發進度,此外,其他公司的架構設計并不一定適用于當前專案,如果強行引入,很可能會導致架構水土不服、運行不流暢等問題,最終需要不斷重構或者推倒重來,因此,架構師或設計師應該深刻理解為何要進行架構設計,避免生搬硬套,針對具體需求進行合理的設計,才能保證專案的順利進行,

1.1.2 架構設計是為了追求高性能、高可用、可擴展性等單一目標

持有這類觀點的人看似具備一定架構經驗或基礎,但實際上他們無論面對什么系統或業務,都會不顧一切地追求這些目標,導致架構設計變得復雜、專案實施時間拖延、團隊內部不和等問題的出現,這些問題使得整個專案進展緩慢,系統穩定性差,出現問題難以解決,甚至加入新功能也需要花費大量時間,這些情況不是危言聳聽,而是廣泛出現的現象,因此,架構師或設計師必須深入了解系統和業務需求,根據實際需要合理設計,不可盲目追求“高XX”目標,才能確保專案開發進度和系統的穩定性,

 

1.2 架構設計的真正目的

整個軟體技術發展的歷史,其實就是一部與“復雜度”斗爭的歷史,架構也是為了應對軟體系統復雜度而提出的一個解決方案,其主要目的是為了解決軟體系統復雜度帶來的問題,
那到底什么是復雜度呢?John Ousterhout教授在 A Philosophy of Software Design 書中提到,復雜度就是任何使得軟體難于理解和修改的因素
復雜的系統有一些非常明顯的特征,John教授將它抽象為變更放大(Change amplification)、認知負荷(Cognitive load)與未知的未知(Unknown unknowns)這3類,
變更放大(Change amplification)指得是看似簡單的變更需要在許多不同地方進行代碼修改,系統開發者之前沒有及時重構代碼,提取公共邏輯,而是省時間Ctrl-C,Ctrl-V式代碼開發(這樣做不會影響已有的穩定模塊,不需要做比較多的回歸測驗,上線風險小),當需求變化時,需要改動多處代碼,
認知負荷(Cognitive load)是指系統的學習與理解成本高,開發人員的研發效率大大降低,
未知的未知(Unknown unknowns)是指不知道修改哪些代碼才能使系統功能正確的運行,也不知道這行代碼的改動是否會引發線上問題,這一項是復雜性中最糟糕的一個表現形式,

 

1.3 系統復雜度的六個來源及通用解法

本段參考 參考5
1.高性能 2.高可用 3.可擴展性 4.低成本 5.安全 6.規模

1.3.1 高性能

軟體系統中高性能帶來的復雜度主要體現在兩方面:
1.一方面是單臺計算機內部為了高性能帶來的復雜度;
2.另一方面是多臺計算機集群為了高性能帶來的復雜度,

1.3.1.1 單機復雜度

計算機內部復雜度最關鍵的地方就是作業系統,計算機性能的發展本質上是由硬體發展驅動的,尤其是 CPU 的性能發展,而將硬體性能充分發揮出來的關鍵就是作業系統,所以作業系統本身也是隨硬體的發展而發展的,作業系統是軟體系統的運行環境,作業系統的復雜度直接決定了軟體系統的復雜度,
作業系統和性能最相關的就是行程和執行緒,
  • 行程:用行程來對應一個作業系統執行的任務,每個任務都有自己獨立的記憶體空間,行程間互不相關,由作業系統來進行調度,

  • 多行程:為了達到多行程并行運行的目的,采取了分時的方式,即把 CPU 的時間分成很多片段,每個片段只能執行某個行程中的指令,

  • 行程間通信:為了解決行程在運行時相互通信的問題,人們設計了各種行程間通信,包括管道、訊息佇列、信號量、共享存盤等,

  • 多執行緒:多行程讓多任務能夠并行處理任務,但本身還有缺點,單個行程內部只能串行處理,而實際上很多行程內部的子任務并不要求是嚴格按照時間順序來執行的,也需要并行處理,為了解決這個問題發明了執行緒,執行緒是行程內部的子任務,但這些子任務都共享同一份行程資料,為了保證資料的正確性,又發明了互斥鎖機制,有了多執行緒后,作業系統調度的最小單位就變成了執行緒,而行程變成了作業系統分配資源的最小單位,
作業系統發展到現在,如果要完成一個高性能的軟體系統,需要考慮如多行程、多執行緒、行程間通信、多執行緒并發等技術點,而且這些技術并不是最新的就是最好的,也不是非此即彼的選擇,
在做架構設計的時候,需要花費很大的精力來結合業務進行分析、判斷、選擇、組合,這個程序同樣很復雜,例如,下面的系統都實作了高性能,但是內部實作差異很大:
  • Nginx 可以用多行程也可以用多執行緒
  • JBoss 采用的是多執行緒
  • Redis 采用的是單行程
  • Memcache 采用的是多執行緒

1.3.1.2 集群復雜度

讓多臺機器配合起來達到高性能的目的,是一個復雜的任務,常見的方式有:
任務可以指完整的業務處理,也可以指某個具體的任務,
1.任務分配:每臺機器都可以處理完整的業務任務,不同的任務分配到不同的機器上執行,
2.任務分解:業務越來越復雜,單臺機器處理的性能會越來越低,為了能夠繼續提升性能,采用任務分解,
1.3.1.2.1任務分配

圖片

  • 增加一個任務分配器,可以是硬體(F5、交換機)、軟體(LVS)、負載均衡軟體(Nginx、HAProxy)、自己開發的系統,
  • 任務分配器與業務服務器之間的連接和互動,
  • 任務分配器增加分配演算法(輪詢、權重、負載),

業務量繼續提升,需要增加任務分配器的數量,

圖片

  • 任務分配器增加為多臺,這樣需要將不同的用戶請求分配到不同的任務分配器上(DNS輪詢、智能DNS、CDN、GSLB全域負載均衡),
  • 任務分配器和業務服務器之間從一對多變成多對多的網狀結構,
  • 業務服務器繼續擴增,狀態管理和故障處理復雜度更大,

1.3.1.2.2 任務分解

微服務架構就采用了這種思路,通過任務分配的方式,能夠突破單臺機器處理性能的瓶頸,通過增加更多的機器來滿足業務的性能需求,但如果業務本身也越來越復雜,單純只通過任務分配的方式來擴展性能,收益會越來越低,

圖片

通過這種任務分解的方式,能夠把原來大一統但復雜的業務系統,拆分成小而簡單但需要多個系統配合的業務系統,從業務的角度來看,任務分解既不會減少功能,也不會減少代碼量(事實上代碼量可能還會增加,因為從代碼內部呼叫改為通過服務器之間的介面呼叫),任務分解能夠提升性能的主要原因是:

1.簡單的系統更容易做到高性能:系統的功能越簡單,影響性能的點就越少,就更加容易進行有針對性的優化,

2.可以針對單個任務進行擴展:當各個邏輯任務分解到獨立的子系統后,整個系統的性能瓶頸更加容易發現,而且發現后只需要針對有瓶頸的子系統進行性能優化或者提升,不需要改動整個系統,風隙訓小很多,

最終決定業務處理性能的還是業務邏輯本身,業務邏輯本身沒有發生大的變化下,理論上的性能是有一個上限的,系統拆分能夠讓性能逼近這個極限,但無法突破這個極限,

1.3.2 高可用

系統無中斷地執行其功能的能力,代表系統的可用性程度,是進行系統設計時的準則之一,

本質上都是通過“冗余”來實作高可用,高可用的“冗余”解決方案,單純從形式上來看,和高性能是一樣的,都是通過增加更多機器來達到目的,但其實本質上是有根本區別的:高性能增加機器目的在于“擴展”處理性能;高可用增加機器目的在于“冗余”處理單元,

通過冗余增強了可用性,但同時也帶來了復雜性,

1.3.2.1 計算高可用

計算的特點是無論從哪臺機器上進行計算,同樣的演算法和輸入資料,產出的結果都是一樣的,所以將計算從一臺機器遷移到另一臺對業務沒有影響,

圖片

  • 需要增加一個任務分配器
  • 任務分配器和真正的業務服務器之間有連接和互動
  • 任務分配器需要增加分配演算法(主備【冷備、溫備、熱備】、主主、多主多倍【2主2備、4主0備】)

1.3.2.2 存盤高可用

對于需要存盤資料的系統而言,整個系統的高可用設計的難點和關鍵點在于“存盤高可用”,存盤和計算的本質區別在于將資料從一臺機器搬移到另一臺機器時需要通過線路進行傳輸,而線路傳輸是存在延遲的,速度在毫秒級別,距離越遠,延遲越高,加之各種例外情況(如傳輸中斷、丟包、擁塞),會導致延遲更高,對于高可用系統來說,在某個時間點通信中斷就意味著整個系統的資料不一致,按照“資料 + 邏輯 = 業務”的公式,資料不一致將導致最終業務表現不同,如果不做冗余備份,系統的整體高可用性無法保證,因此,存盤高可用的難點不在于如何備份資料,而在于如何減少或規避資料不一致對業務造成的影響,

分布式領域內著名的 CAP 定理從理論上證實了存盤高可用的復雜度,存盤高可用不可能同時滿足“一致性、可用性、磁區容忍性”,最多只能滿足其中兩個,因此,在進行架構設計時需要結合業務進行取舍,

1.3.3 可擴展性

可擴展性指系統為了應對將來需求變化而提供的一種擴展能力,當有新的需求出現時,系統不需要或者僅需要少量修改就可以支持,無須整個系統重構或者重建,

在軟體開發領域,面向物件思想的提出,就是為了解決可擴展性帶來的問題;設計模式更是將可擴展性做到了極致,

設計具備良好可擴展性的系統,有兩個基本條件:

  • 正確預測變化

  • 完美封裝變化

1.3.3.1 預測變化

“唯一不變的是變化”,按照這個標準衡量,架構師每個設計方案都要考慮可擴展性,預測變化的復雜性在于:

  • 不能每個設計點都考慮可擴展性

  • 不能完全不考慮擴展性

  • 所有的預測都存在出錯的可能性

如何把握預測的程度和提升預測結果的準確性,是一件很復雜的事情,而且沒有通用的標準,更多是靠經驗、直覺,

1.3.3.2 應對變化

預測變化是一回事,采取什么方案來應對變化,又是另外一個復雜的事情,即使預測很準確,如果方案不合適,則系統擴展一樣很麻煩,

微服務架構中的各層進行封裝和隔離也是一種應對變化的解決方式,

1.3.3.2.1 變化層VS穩定層

第一種應對變化的常見方案是將“變化”封裝在一個“變化層”,將不變的部分封裝在一個獨立的“穩定層”,

無論是變化層依賴穩定層,還是穩定層依賴變化層都是可以的,需要根據具體業務情況來設計,

無論采取哪種形式,通過剝離變化層和穩定層的方式應對變化,都會帶來兩個主要的復雜性相關的問題,

1.系統需要拆分出變化層和穩定層(如何拆分)

2.需要設計變化層和穩定層之間的介面(穩定層介面越穩定越好,變化層介面從差異中找到共同點)

1.3.3.2.2 抽象層VS實作層

第二種常見的應對變化的方案是提煉出一個“抽象層”和一個“實作層”,

抽象層是穩定的,實作層可以根據具體業務需要定制開發,當加入新的功能時,只需要增加新的實作,無須修改抽象層,這種方案典型的實踐就是策略模式,

1.3.4 低成本

在設計高性能、高可用的架構方案時,如果涉及到數百、數千甚至數萬臺服務器,成本就會成為一個非常重要的考慮點,為了控制成本,需要減少服務器的數量,這與增加更多服務器來提升性能和可用性的通用做法相沖突,因此,低成本往往不是架構設計的首要目標,而是一個附加約束,為了解決這個問題,需要先設定一個成本目標,然后根據高性能和高可用的要求設計方案,并評估是否能夠滿足成本目標,如果不能,就需要重新設計架構;如果無論如何都無法設計出滿足成本要求的方案,那只能找老板調整成本目標了,低成本給架構設計帶來的主要復雜度體現在,往往只有"創新"才能達到低成本目標,"創新"的含義是開創一個全新的技術領域,或者引入新技術來解決問題,如果沒有找到能夠解決自己問題的新技術,那么就需要自己創造新技術了,例如,NoSQL(如Memcache、Redis等)是為了解決關系型資料庫無法應對高并發訪問帶來的訪問壓力;全文搜索引擎(如Sphinx、Elasticsearch、Solr)是為了解決關系型資料庫like搜索的低效問題;Hadoop則是為了解決傳統檔案系統無法應對海量資料存盤和計算的問題,創造新技術的主要復雜度在于需要創造全新的理念和技術,并且新技術需要與舊技術相比有質的飛躍,

1.3.5 安全

從技術的角度來講,安全可以分為兩類:

  • 一類是功能上的安全,

  • 一類是架構上的安全,

1.3.5.1 功能安全

常見的 XSS 攻擊、CSRF 攻擊、SQL 注入、Windows 漏洞、密碼破解等,本質上是因為系統實作有漏洞,黑客有了可乘之機,功能安全其實就是“防小偷”,

從實作的角度來看,功能安全更多地是和具體的編碼相關,與架構關系不大,開發框架會內嵌常見的安全功能,但是開發框架本身也可能存在安全漏洞和風險,

所以功能安全是一個逐步完善的程序,而且往往都是在問題出現后才能有針對性的提出解決方案,我們永遠無法預測系統下一個漏洞在哪里,也不敢說自己的系統肯定沒有任何問題,

換句話講,功能安全其實也是一個“攻”與“防”的矛盾,只能在這種攻防大戰中逐步完善,不可能在系統架構設計的時候一勞永逸地解決,

1.3.5.2 架構安全

如果說功能安全是“防小偷”,那么架構安全就是“防強盜”,

架構設計時需要特別關注架構安全,尤其是互聯網時代,理論上來說系統部署在互聯網上時,全球任何地方都可以發起攻擊,

傳統的架構安全主要依靠防火墻,防火墻最基本的功能就是隔離網路,通過將網路劃分成不同的區域,制定出不同區域之間的訪問控制策略來控制不同信任程度區域間傳送的資料流,

防火墻的功能雖然強大,但性能一般,所以在傳統的銀行和企業應用領域應用較多,但在互聯網領域,防火墻的應用場景并不多,

互聯網系統的架構安全目前并沒有太好的設計手段來實作,更多地是依靠運營商或者云服務商強大的帶寬和流量清洗的能力,較少自己來設計和實作,

1.3.6 規模

規模帶來復雜度的主要原因就是“量變引起質變”,當數量超過一定的閾值后,復雜度會發生質的變化,常見的規模帶來的復雜度有:

1.功能越來越多,系統復雜度指數級上升

2.資料越來越多,系統復雜度發生質變

1.3.6.1 功能越來越多,系統復雜度指數級上升

例如,某個系統開始只有 3 大功能,后來不斷增加到 8 大功能,雖然還是同一個系統,但復雜度已經相差很大了,具體相差多大呢?我以一個簡單的抽象模型來計算一下,假設系統間的功能都是兩兩相關的,系統的復雜度 = 功能數量 + 功能之間的連接數量,通過計算我們可以看出:3個功能的系統復雜度為3+3=6

8個功能的系統復雜度為8+(7+0)*8/2=36 可以看出,具備8個功能的系統的復雜度不是比具備 3 個功能的系統的復雜度多5,而是多了30,基本是指數級增長的,主要原因在于隨著系統功能數量增多,功能之間的連接呈指數級增長,下圖形象地展示了功能數量的增多帶來了復雜度,

圖片

1.3.6.2 資料越來越多,系統復雜度發生質變

隨著資料量的不斷增長,傳統的資料處理和管理方式已經無法適應,因此“大資料”這一概念應運而生,大資料的誕生主要是為了解決資料規模變得越來越大時,傳統的資料收集、存盤、分析等方式無法勝任的問題,Google的三篇技術論文,即Google File System、Google Bigtable和Google MapReduce則分別開創了大資料檔案存盤、列式資料存盤和大資料運算的技術領域,即便資料規模沒有達到大資料的水平,資料增長仍然可能會給系統帶來復雜性,例如,在使用關系資料庫存盤資料時,當單表資料達到一定規模時,就會導致添加索引、修改表結構等操作變得很慢,可能需要幾個小時,這就會對業務造成不良影響,因此,必須考慮將單表拆分為多表來解決這個問題,但這個程序也會引入更多的復雜性,

 

1.4 簡單的復雜度分析案例

我們來分析一個簡單的案例,一起來看看如何將“架構設計的真正目的是為了解決軟體系統復雜度帶來的問題”這個指導思想應用到實踐中,

當我們設計一個大學的學生管理系統時,我們需要考慮該系統的復雜度以及如何解決這些復雜度帶來的問題,首先,我們可以將該系統的復雜度分為以下幾個方面:

性能 該系統的訪問頻率并不高,因此性能并不是一個很大的問題,我們可以使用MySQL作為存盤,Nginx作為Web服務器,無需考慮快取,

可擴展性 該系統的功能比較穩定,可擴展的空間并不大,因此可擴展性方面也不是一個很大的問題,

高可用 資料丟失是不可接受的,故該系統的高可用性方面需要考慮多種例外情況,如機器故障、機房故障等,為此,我們需要設計MySQL同機房主備方案和MySQL跨機房同步方案,

安全性 該系統存盤的資訊涉及到學生的隱私,因此需要考慮安全性,我們可以使用Nginx提供的ACL控制、用戶賬號密碼管理和資料庫訪問權限控制來保證系統的安全性,

成本 由于該系統比較簡單,基本上幾臺服務器就可以搞定,因此成本方面并不需要太多關注,

規模 同上,規模復雜度無需過度關注,

總體來說,我們需要在架構設計中充分考慮系統的復雜度,同時根據不同問題選擇合適的解決方案,以提高系統的可靠性和安全性,

 

1.5 總結

第一章提出了架構的根本目是解決系統復雜度,并簡要說明系統復雜度的六個來源及通用解法,為我們設計架構提供了清晰可執行的操作思路,

二、微服務架構解決了高可用、可擴展問題,但性能下降、成本&規模復雜度暴增

我們知道,這些年來隨著設備和新技術的發展,軟體的架構模式發生了很大的變化,軟體架構模式大體來說經歷了從單機、集中式到分布式微服務架構三個階段的演進 ,隨著分布式技術的快速興起,我們已經進入到了微服務架構時代,

圖片

 

2.1 微服務架構的優點

與傳統單體應用架構相比,微服務架構有很多優點,具體表現如下:

2.1.1 高可用

當架構中的某一組件發生故障時,在單一行程的傳統架構下,故障很有可能在行程內擴散,導致整個應用不可用,在微服務架構下,故障會被隔離在單個服務中,若設計良好,其他服務可通過重試、平穩退化等機制實作應用層面的容錯,

2.1.4 可擴展

單個服務應用也可以實作橫向擴展,這種擴展可以通過將整個應用完整的復制到不同的節點中實作,當應用的不同組件在擴展需求上存在差異時,微服務架構便體現出其靈活性,因為每個服務可以根據實際需求獨立進行擴展,

 

2.2 微服務的缺點

2.2.1 復雜度高

與單體式架構相比,微服務會導致復雜性上升,因為多個團隊會在更多地方創建更多服務,若管理不當,則會導致開發速度和效率降低,

2.2.2 基礎設施成本呈指數級增長

每個新的微服務都有自己的成本,例如測驗工具、托管基礎架構和監控工具等方面,

2.2.3 性能下降

微服務之間通過REST、RPC等形式進行互動,通信的時延會受到較大的影響,

三、DDD幫助微服務控制規模復雜度

 

3.1 控制成本&規模復雜度需要明晰微服務的邊界

由1.3.6.1 所述,隨著微服務數量上升,規模復雜度呈指數級上升,那么我們理應控制微服務的數量,這就帶來了爭論和疑惑:微服務的粒度應該多大呀?微服務到底應該如何拆分和設計呢?

長期以來,微服務架構缺乏一套系統的理論和方法來指導其拆分,這導致了一些人對微服務架構的理解出現了一些曲解,有人簡單地認為微服務只是將原來的單體應用程式拆分為多個部署包或更換為支持微服務架構的技術框架,便可成為微服務,還有人認為,微服務越小越好,

然而,在過去的幾年中,一些專案由于在前期過度拆分微服務,導致專案復雜度過高,無法進行上線和運維的情況已經出現,綜合來看,我認為微服務拆分困境的根本原因在于不清楚業務或微服務的邊界在哪里,換句話說,只有確定了業務邊界和應用邊界,這個困境才能迎刃而解,

 

3.2 DDD能夠幫我們設計出清晰的領域和應用邊界

DDD 包括戰略設計和戰術設計兩部分,戰略設計主要從業務視角出發,建立業務領域模型,劃分領域邊界,建立通用語言的限界背景關系,這些限界背景關系可以作為微服務設計的參考邊界,而戰術設計則從技術視角出發,著重于領域模型的技術實作,包括聚合根、物體、值物件、領域服務、應用服務和資源庫等代碼邏輯的設計和實作,

在戰略設計程序中,領域模型的建立是重中之重,為此,DDD 提出了事件風暴這一建立領域模型的方法,事件風暴是一個從發散到收斂的程序,通常采用用例分析、場景分析和用戶旅程分析,全面分解業務領域,梳理領域物件之間的關系,這是一個發散的程序,在事件風暴程序中,會產生很多物體、命令、事件等領域物件,我們將這些領域物件從不同的維度進行聚類,形成如聚合、限界背景關系等邊界,建立領域模型,這就是一個收斂的程序,

因此,DDD 可以幫助軟體工程師建立清晰的領域模型,劃分業務和應用邊界,以指導微服務的設計和拆分,事件風暴是建立領域模型的主要方法,通過其發散的程序和聚合的程序,建立起合理的領域模型,從而實作高效的軟體開發和落地,

圖片

我們可以用三步來劃定領域模型和微服務的邊界,

  • 在領域驅動設計的戰略設計中,我們采用事件風暴方法梳理業務程序中的用戶操作、事件以及外部依賴關系等,從而梳理出領域物體等領域物件,
  • 然后,我們根據領域物體之間的業務關聯性,形成聚合,并確定聚合中的聚合根、值物件和物體,
  • 接著,根據業務及語意邊界等因素,將一個或多個聚合劃定在一個限界背景關系內,形成領域模型,這個程序中,我們建立了領域模型,劃定了業務領域的邊界,建立了通用語言和限界背景關系,確定了領域模型中各個領域物件的關系,這些限界背景關系可以作為微服務設計的參考邊界,從而確定了應用端的微服務邊界,

在從業務模型向微服務落地的程序中,即從戰略設計向戰術設計的實施程序中,我們會將領域模型中的領域物件與代碼模型中的代碼物件建立映射關系,將業務架構和系統架構進行系結,當調整業務架構和領域模型以回應業務變化時,系統架構也會同時發生調整,并同步建立新的映射關系,這種方式可以幫助我們實作高效的軟體開發和落地,從而更好地應對業務需求變化,

因此,通過領域驅動設計的戰略設計和戰術設計,我們可以清晰地劃定領域邊界,建立領域模型,幫助我們實作微服務的設計和拆分,同時也能夠有效地回應業務變化,提高軟體開發和落地的效率,

 

3.3 微服務與DDD的異同

DDD 是一種面向復雜業務領域的設計方法論,而微服務是一種面向分布式系統的架構風格,它們的共同目標都是通過將系統分解為更小,更易于管理的組件來提高系統的可維護性和可擴展性,

  • 在 DDD 中,我們關注的是業務領域的劃分和領域模型的設計,以便更好地理解業務需求,并將其轉化為可執行的代碼,
  • 在微服務中,我們主要關注的是運行時的通信,容錯和故障隔離,以及服務治理等問題,以確保各個微服務可以獨立開發、測驗、構建和部署,
  • 通過結合 DDD 和微服務,我們可以更好地實作高效的業務邏輯,同時也可以充分利用微服務的優點,提高應用程式的可擴展性和可維護性,因此,DDD 和微服務是互補的,可以共同用于構建可靠且高效的應用程式,

 

參考

1.01 架構、復雜度與三原則:https://promacanthus.netlify.app/computer-science/architecture/01-%E6%9E%B6%E6%9E%84%E5%A4%8D%E6%9D%82%E5%BA%A6%E4%B8%8E%E4%B8%89%E5%8E%9F%E5%88%99/#011-%E7%B3%BB%E7%BB%9F%E4%B8%8E%E5%AD%90%E7%B3%BB%E7%BB%9F
2.https://zhuanlan.zhihu.com/p/372225207
3.https://www.itcast.cn/news/20220329/17575248138.shtml
4.https://zq99299.github.io/note-book2/ddd/01/01.html#%E8%BD%AF%E4%BB%B6%E6%9E%B6%E6%9E%84%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%BC%94%E8%BF%9B
5.https://time.geekbang.org/column/article/6990
作者|王軒宇(昭運)

本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/An-article-reveals-what-problem-DDD-has-solved.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/552412.html

標籤:其他

上一篇:一文揭秘DDD到底解決了什么問題

下一篇:返回列表

標籤雲
其他(159007) Python(38129) JavaScript(25421) Java(18034) C(15226) 區塊鏈(8265) C#(7972) AI(7469) 爪哇(7425) MySQL(7184) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5871) 数组(5741) R(5409) Linux(5340) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4572) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2433) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1972) 功能(1967) Web開發(1951) HtmlCss(1936) python-3.x(1918) C++(1915) 弹簧靴(1913) xml(1889) PostgreSQL(1876) .NETCore(1860) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 一文揭秘DDD到底解決了什么問題

    DDD作為架構設計思想幫助微服務控制規模復雜度,那它是怎么做到的呢? 一、架構設計是為了解決系統復雜度 談到架構,相信每個技術人員都是耳熟能詳,但如果深入探討一下,“為何要做架構設計?”或者“架構設計目的是什么?”類似的問題,大部分人可能從來沒有思考過,或者即使有思考,也沒有太明確可信的答案。 1. ......

    uj5u.com 2023-05-14 09:32:36 more
  • 一文揭秘DDD到底解決了什么問題

    DDD作為架構設計思想幫助微服務控制規模復雜度,那它是怎么做到的呢? 一、架構設計是為了解決系統復雜度 談到架構,相信每個技術人員都是耳熟能詳,但如果深入探討一下,“為何要做架構設計?”或者“架構設計目的是什么?”類似的問題,大部分人可能從來沒有思考過,或者即使有思考,也沒有太明確可信的答案。 1. ......

    uj5u.com 2023-05-14 09:26:48 more
  • 分布式系統常見問題

    一.概述 分布式系統存在網路,時鐘,以及許多不可預測的故障。分布式事務,一致性與共識問題,迄今為止仍沒有得到很好的解決方案。要想完美地解決分布式系統中的問題不太可能,但是實踐中應對特定問題仍有許多可靠的解決方案。本文不會談及諸如BASE, CAP, ACID 等空泛的理論,只基于實踐中遇到的問題提出 ......

    uj5u.com 2023-05-14 08:32:39 more
  • 分布式系統常見問題

    一.概述 分布式系統存在網路,時鐘,以及許多不可預測的故障。分布式事務,一致性與共識問題,迄今為止仍沒有得到很好的解決方案。要想完美地解決分布式系統中的問題不太可能,但是實踐中應對特定問題仍有許多可靠的解決方案。本文不會談及諸如BASE, CAP, ACID 等空泛的理論,只基于實踐中遇到的問題提出 ......

    uj5u.com 2023-05-14 08:31:54 more
  • 詳解快取更新策略及如何選擇

    概述 快取更新是指在資料發生變化時,保持快取和資料庫的資料一致性的問題。如果快取和資料庫的資料不一致,會導致用戶看到過期或者錯誤的資料,影響業務邏輯和用戶體驗。 為了實作快取更新,我們可以采用以下四種方式其中的一種: Cache Aside策略:應用程式直接與資料庫和快取互動,并負責維護快取的一致性 ......

    uj5u.com 2023-05-13 08:54:04 more
  • Java設計模式【單例模式】

    Java設計模式【單例模式】 單例模式 單例模式(Singleton Pattern)是一種創建型設計模式,其主要目的是確保一個類只有一個實體,并提供對該實體的唯一訪問點。 優缺點 優點: 提供了對唯一實體的受控訪問。 由于在系統記憶體中只存在一個物件,因此可以節約系統資源。 缺點: 單例類的擴展有很 ......

    uj5u.com 2023-05-13 08:53:55 more
  • Java設計模式簡介(總結)

    Java設計模式簡介(總結) 什么是設計模式 Java設計模式是一組經過驗證的解決特定問題的編程技術,這些技術可以幫助開發人員快速、有效地開發高質量的軟體。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 設計模式分類 設計模式一般分為三大類:創建型、結構型、行為型,具體分類如 ......

    uj5u.com 2023-05-13 08:53:48 more
  • 長文多圖一步步講清楚:DDD理論、建模與代碼實作全流程

    1 六個問題 1.1 為什么使用DDD DDD方法論核心是將問題不斷分解,把大問題分解為小問題,大業務分解小領域,簡而言之就是分而治之,各個擊破。 分而治之是指直接面對大業務我們無從下手,需要按照一定方法進行分解,分解為高內聚的小領域,使得業務有邊界清晰,而這些小領域是我們有能力處理的,這就是領域驅 ......

    uj5u.com 2023-05-13 08:53:43 more
  • Java設計模式【單例模式】

    Java設計模式【單例模式】 單例模式 單例模式(Singleton Pattern)是一種創建型設計模式,其主要目的是確保一個類只有一個實體,并提供對該實體的唯一訪問點。 優缺點 優點: 提供了對唯一實體的受控訪問。 由于在系統記憶體中只存在一個物件,因此可以節約系統資源。 缺點: 單例類的擴展有很 ......

    uj5u.com 2023-05-13 08:53:28 more
  • Java設計模式簡介(總結)

    Java設計模式簡介(總結) 什么是設計模式 Java設計模式是一組經過驗證的解決特定問題的編程技術,這些技術可以幫助開發人員快速、有效地開發高質量的軟體。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 設計模式分類 設計模式一般分為三大類:創建型、結構型、行為型,具體分類如 ......

    uj5u.com 2023-05-13 08:53:20 more