1. 程式人生 > >可落地的DDD的(2)-為什麼說MVC工程架構已經過時

可落地的DDD的(2)-為什麼說MVC工程架構已經過時

摘要

mvc是一種軟體設計模式,最早由Trygve Reenskaug在1978年提出,他有效的解決了表示層,控制器層,邏輯層的程式碼混合在一起的問題,很好的做到了職責分離。但是在實際的編碼實踐過程中,你會發現這個模式隨著業務的擴充套件,變的邏輯混亂,程式碼重合度很高。這裡提出借鑑DDD思想的一種新的工程結構

mvc的問題

通常一個前後端分離的系統,後端工程系統結構圖通常下面這樣

  1. 四層 controller/service/manager/mapper

  2. 不可以同級呼叫

  3. 上級可以知曉下級,下級不可知曉上級,也就是bean的轉化放在上級

這個分層結構職責分離是按照縱向切分的

  1. 資源服務層repository是面向DB程式設計

  2. service層是面向前端頁面程式設計。

也就是說,對於某一塊的業務,他沒有將邏輯抽象到一起,他只是將一次request按照縱向切分了。沒有進行橫向的業務切分。
這樣將會導致的問題
職責分散,邏輯重複度高

  • bean的建立太隨意,基本就是一個需求對應一些dto, vo,query bean
  • 不同開發者對於同一個領域的東西有不同的bean,同一個開發者對於相同邏輯的bean,過了幾個月,又定義出一個差不多的bean

沒有邊界

  • 根本沒有上下文/邊界的概念,比如說店鋪會和使用者有互動,訂單會和使用者有互動,通常在DB儲存時只會存關聯id,然後需要去取對應的名稱,其他屬性資訊。這些資訊的獲取,有些開發在manager層操作,然後將屬性定義到了店鋪相關的DTO中;有些放在了service層做。controller/service/manager各個層次都可以呼叫,沒有任何約束。

mvc的演進

按照上述的說明,在一個單體服務中,隨著業務的不斷迭代,可能會發生什麼嚴重的問題。

舉幾個真實鮮活的例子

分庫分表的例子
實體A是我們業務中的一個基礎的重要的實體,對應的資料表tableA,一開始業務很簡單,只有1個服務,在這個服務裡面呼叫。後來業務擴張了,有十幾個服務了,然後十幾個服務直接查這個tableA。tableA也擴張成為了tableA,tableB,tableC。有些人覺得程式碼重複度高了,將mapper/manager層拆成共通的部分打成一個jar包,然後各個微服務中引入這個jar。業務變得更加複雜了,服務擴充套件到幾十個了,tableA資料也有幾千萬了,這時候要做分庫分表了,怎麼整。

最後花了差不多1年,涉及十幾個團隊,才把這個mapper/manager呼叫改掉,然後做分庫分表。

有人可能覺得這個只要在服務拆分時,避免直接呼叫就可以了,那再舉個其他型別的例子。

使用者等級的例子

使用者的等級,使用者的分級是很複雜的,不同的業務階段有這個不同的定義。比如一開始定義一個欄位叫grade的代表使用者等級。
然後各個業務都在查這個表的欄位grade進行判斷,然後產品需要改了,增加了判斷必須同時要達到什麼條件才能稱作等級x。這時候你又得滿世界的改了。

DDD的工程架構

那如何運用DDD的思想進行改造呢
核心思想:封裝領域內的邏輯,統一對外暴露的入口,防止業務邏輯洩露。

  • 在mvc縱向切分的基礎上,增加一層領域的橫向切分
  • 同一個工程裡面,領域之間的呼叫只能通過domainService,這樣可以遮蔽領域內的資料庫是如何持久化的,業務邏輯是如何判斷的、演算法是如何實現的。
    service之間可以直接呼叫。
  • 領域內還是縱向切分,安裝mvc分層結構。

上面的只是一個草圖,我們真實的結構圖比這要稍微複雜些。領域內會區分領域物件,領域服務,基礎設施層。這樣在領域內進行指責分離,不過從實際的執行過程中領域內的比較細節,執行起來ROI比較低,推薦大家可以先按這套執行。

畫外音:估計有些程式設計師看到這個工程結構變化呵呵一笑,覺得沒多大價值,沒什麼改變必要。

這種工程的結構劃分從提出來的到真正被我們團隊成員接受的時間週期差不多是8個月。
原因大概是這麼幾類

  1. 引入新的分層,太複雜了,增加了程式碼複雜度
  2. 我這塊業務很簡單,CRUD就行了,沒涉及到服務之間的互動。直接mvc一條道走到黑就可以。

如果你看這篇文章也是這種感受,不妨花點時間看下你們業務的程式碼,看看重複度有多高,看看邏輯有多散亂。你就會明白。

DDD工程的演進

DDD工程的演進也就是服務的拆分了,放到下期講。

總結

很多DDD的文章都在說傳統的程式設計方式是面試資料庫程式設計,導致物件中只有getter,setter,也就是貧血模型,貧血模型是沒有業務邏輯,面向過程設計,不符合面向物件設計原則。

對於這個結論我是同意的,但是對於造成的原因不是很同意。個人認為造成這個原因的主要原因還是在於長期以來的MVC這種模式只有縱向切分導致。如果結合橫向切分,有沒有DDD也無所謂。這裡再引用一下驅動方法不能改變任何事情這段話,如果你能深入理解職責、封裝。並隨著業務的迭代,不斷的重構你的程式碼,那麼你不需要什麼DDD,或者其他方法論。

使用職責、封裝和組合;
以介面的視角思考,即“人們如何使用我的元件?”;
使用相關技術寫好程式碼,包括可讀性、資訊性、簡潔、自描述,儘量避免顯式地使用模式;
有能力回答特定業務的“本質”;“本質”是一個模型,但不意味著類和方法,它意味著回答問題“這個業務如何真正地工作?”

因為這些約束,都是強迫你去思考,去做職責的思考,去做模組的封裝。如果你/你團隊成員已經領會其中的道理並很好的運用,還需要這些條條框框幹嗎呢?

下一篇領域與微服務劃分,欲知後事如何,請聽下回分解。

相關閱讀

https://www.cnblogs.com/stoneFang/p/10888630.html

關注【方丈的寺院】,第一時間收到文章的更新,與方丈一起開始技術修行之路

相關推薦

落地DDD的(2)-為什麼說MVC工程架構已經過時

摘要 mvc是一種軟體設計模式,最早由Trygve Reenskaug在1978年提出,他有效的解決了表示層,控制器層,邏輯層的程式碼混合在一起的問題,很好的做到了職責分離。但是在實際的編碼實踐過程中,你會發現這個模式隨著業務的擴充套件,變的邏輯混亂,程式碼重合度很高。這裡提出借鑑DDD思想的一種新的工程結構

也許後端MVC的說法已經過時

呃,標題有點聳人聽聞,不過我並不是標題黨。考慮到談論大而虛的東西(比如最好的語言)容易引起爭論,所以還請諸君帶著看戲而不是庭辯的心態來看待本文。 依我個人所見,後端框架,類似於MVC這樣的組織方式已經顯得過氣了。 過去,在建立應用時通常會按MVC各建一個資料夾,每個資

落地DDD(4)-如何利用DDD進行微服務的劃分(2)

摘要 在前面一篇介紹瞭如何通過DDD的思想,來調整單體服務內的工程結構,為微服務的拆分做準備。同時介紹了我們在進行微服務拆分的時候踩過的一些坑。 這篇介紹下我們最終的方案,不一定對,歡迎留言討論。 微服務劃分 問題分析 上篇介紹過我們一開始的服務劃分標準 一個領域一個服務的規則去拆分, 同時為了保證領域的

移動端工程架構與後端工程架構的思想摩擦之旅(2

此文已由作者黎星授權網易雲社群釋出 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗     投放工程架構調整   有了前面的“理論基礎”,以及躍躍欲試的心動,我們來對投放工程的架構做一次調整和優化,原則是不改變原有的業務邏輯,目的是使投放工程的業務邊界和業務功能更為

Atitit 微服務的優點和拆分 目錄 1. 微服務架構五大優勢 崛起勢頭不可擋 4 1 1.1. 1、複雜度控 6避免“盲人摸象” 7 2 1.2. 2、靈活擴充套件 7 2 1.3. 3、獨立部

Atitit 微服務的優點和拆分 目錄 微服務架構五大優勢 崛起勢頭不可擋4 1、複雜度可控6避免“盲人摸象”7 2、靈活可擴充套件7 3、獨立部署7

落地DDD(3)-如何利用DDD進行微服務的劃分

摘要 前面兩篇介紹了DDD的目標管理、DDD的工程結構調整。這篇討論微服務的劃分。微服務是目前後端比較流行的架構體系了,那麼如何做好一個微服務的劃分?一個微服務的粒度應該是多大呢?這篇主要介紹如何結合DDD進行領域劃分。 工程結構程式碼 上篇介紹了可落地的DDD的(2)-為什麼說MVC工程架構已經過時 很多朋

等保2.0來了,分享一個落地的等保建設方案

企業在安全方面最關注的其實是業務安全、資料安全與安全檢查,這篇文章來講解一下我對於等保過檢的經驗與建設。 不同於其他建設文章,本文會給出很多落實方面的建議與方法,希望企業可以通過這篇文章,順利通過過檢任務,並保證安全的投入成本與收益的比率。   一、管理 一個企業的安全性最終體現在管理與

ABP官方文檔翻譯 1.2 N層架構

分層 幫助 代碼復用 ajax請求 one 添加 數據 mapper 搜索引擎搜索 N層架構 介紹 ABP架構 其他(通用) 領域層 應用層 基礎設施層 網絡和展現層 其他 總結 介紹   應用程序代碼庫的分層架構是被廣泛認可的可以減少程序復雜度、提高代碼復用率的

ABP官方文檔翻譯 6.1.2 MVC視圖

tar strong http span 繼承 ant net 方法 mvc視圖 ASP.NET MVC 視圖 介紹 AbpWebViewPage基類 介紹   ABP通過Abp.Web.Mvc nuget包集成到MVC視圖。你可以如往常一樣創建正常的MVC

OpenStack pike版 基本環境部署(2) 續案例架構(1)

duyuheng 基本環境部署 續案例架構(1)環境準備工作:按照以下規劃配置各主機IP地址及主機名稱# controller10.0.0.11 controller# compute110.0.0.31 compute1# block110.0.0.41 bloc

Node實現簡單的註冊時後端的MVC模型架構

del 引入 數據庫 reg god 定義 hash oba router 實現一個簡單的註冊界面後端MVC模型架構 第一步:在生成的express框架的app.js中添加一個路由,代碼如下:var api = require(‘./routes/api‘);

中小企業參考的數據庫架構-mysql篇

負載 bic 主從 node jaf sel dba 相同 nbsp 引言 數據庫在眾多互聯網公司中應用日益廣泛,不同的公司,使用姿勢不盡相同,尤其是大公司,各種自研架構,羨煞旁人。但是,作為中小企業,由於分工和團隊規模限制,很難實現自研,大多數情況下,使用開源架構。 目前

Webpack + React全棧工程架構項目實戰精講

獨立 小白 l數據庫 java並發編程 前端工程師 inux 微服務架構 算法 經典 詳情請交流 QQ 709639943 01、Webpack + React全棧工程架構項目實戰精講 02、跨平臺混編框架 MUI 仿豆瓣電影 APP 03、Node.js入門到企

工作總結:mvc分層架構

結束 調用 磁盤io userinfo 容易 事情 不存在 指定 範圍 pojo:plain ordinary java object 簡單無規則java對象,我個人覺得它和其他不是一個層面上的東西,VO和PO應該都屬於它 po:persistant object 持久對象

2.Docker的架構

架構模式 docker 倉庫 機器 https 對象 通過命令 dig ner 鏡像 一、架構 Docker 使用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和創建Docker容器。 Docker 容器通過 Docker 鏡像來創建。 容器與鏡像的關系類似

zabbix3.2 C/S架構搭建文檔

sql mysql 變量 創建 .com .gz 搭建lamp fix 配置 flush zabbix 是用PHP開發的。得需要搭建LAMP環境 zabbix-server 192.168.1.101zabbix-agent 192.168.1.105 zabbix 下

Spring MVC工程入門

程序員 ati exp ssi resources VC 接下來 文件 internal SpringMVC是一個MVC架構的具體實現,由於其良好的模塊解耦和依賴註入等特性,近年來在各大企業運用非常廣泛。SpringMVC是一個web框架,它常見的配置是采用xml文件配置,

spring-構建mvc工程

stack erl 另一個 分享圖片 fir owa img rect contex SpringMVC基於模型-視圖-控制器(MVC)模式實現,可以構建松耦合的web應用程序。 1、SpringMVC的請求過程 1)請求離開瀏覽器,並攜帶用戶所請求的內容 2)Dispa

mysql 架構篇系列 2 復制架構一主一從搭建(異步復制)

stat 如果 rep 目的 end com version none 3.6 一. 環境準備   1.1 主庫環境(172.168.18.201) 環境 說明 查看腳本 操作系統版本 CentOS Linux release 7.4.1708

02-2 MVC

javaEE的設計模式 歷史沿革:  1. model1(jsp + javaBean) jsp承擔了給使用者顯示和處理內部邏輯的任務,不安全,也不利於維護  2. model2 -> MVC(今天的主題)     Servlet