DDD落地:從網易新聞APP重構,看DDD的巨大價值

尼恩說在前面

在40歲老架構師 尼恩的讀者交流群(50+)中,最近有小伙伴拿到了一線互聯網企業如阿里、滴滴、極兔、有贊、希音、百度、網易、美團的面試資格,遇到很多很重要的面試題:

談談你的DDD落地經驗?

談談你對DDD的理解?

如何保證RPC代碼不會腐爛,升級能力強?

微服務如何拆分?

微服務爆炸,如何解決?

你們的項目,DDD是怎么落地實操的?

所以,這里尼恩給大家做一下系統化、體系化的梳理,使得大家可以充分展示一下大家雄厚的 “技術肌肉”,讓面試官愛到 “不能自已、口水直流”

也一并把這個題目以及參考答案,收入咱們的 《尼恩Java面試寶典PDF》V130版本,供后面的小伙伴參考,提升大家的 3高 架構、設計、開發水平。

《尼恩 架構筆記》《尼恩高并發三部曲》《尼恩Java面試寶典》的PDF,請到文末公號【技術自由圈】獲取

除了本文,尼恩輸出了一個 《從0到1,帶大家精通DDD》系列,幫助大家徹底掌握DDD,地址是:

《阿里DDD大佬:從0到1,帶大家精通DDD》

《阿里大佬:DDD 落地兩大步驟,以及Repository核心模式》

《阿里大佬:DDD 領域層,該如何設計?》

《極兔面試:微服務爆炸,如何解決?Uber 是怎么解決2200個微服務爆炸的?》

《阿里大佬:DDD中Interface層、Application層的設計規范》

《字節面試:請說一下DDD的流程,用電商系統為場景》

《DDD如何落地:去哪兒的DDD架構實操之路》

《DDD落地:從騰訊視頻DDD重構之路,看DDD極大價值》

《DDD落地:從美團抽獎平臺,看DDD在大廠如何落地?》

《美團面試:微服務如何拆分?原則是什么?》

《DDD神藥:去哪兒結合DDD,實現架構大調優》

大家可以先看前面的文章,再來看本篇,效果更佳。

另外,尼恩會結合一個工業級的DDD實操項目,在第34章視頻《DDD的學習圣經》中,給大家徹底介紹一下DDD的實操、COLA 框架、DDD的面試題。

DDD現在非常火爆,是有其巨大生產價值,經濟價值的, 絕不僅僅是一套概念那么簡單。

DDD的絕大價值,具體請參見以下視頻:

從騰訊視頻DDD重構案例,看看DDD極大價值

文章目錄

    • 尼恩說在前面
    • 網易新聞App架構重構實踐
    • 移動端架構與網站架構的區別
    • 網易新聞客戶端的架構演進歷程
      • 第一階段:Static Method
      • 第二階段:MVP
      • 第三階段:MVPs
      • 第四階段:符合 DDD 的 VIPER
    • 基于 DDD 的短視頻架構優化
    • DDD 的選型與實踐
      • 選型背景
      • 落地難題
      • 重構效果
    • DDD 落地面面觀
    • 說在最后
    • 尼恩技術圣經系列PDF

網易新聞App架構重構實踐

作者:小智

嘉賓:李云鵬,網易新聞架構技術組工程師,國內首個移動架構模型書籍《移動開發架構設計實戰》作者。10 余年互聯網行業經驗,擅長移動端架構選型、項目重構與插件開發相關工作。曾就職于世界 500 強核心技術實驗室,作為第一發明人,申請了 14 項專利和著作權。

當前,大多數移動開發團隊將 MVP 作為業務層的核心架構模式,并在此基礎上實現了客戶端的組件化、插件化、容器化等。然而,作為業務層核心的 MVP 架構模式仍存在諸多問題。在領域驅動設計(DDD)思想的指導下,網易新聞 App 對其架構進行了全面重構,取得了良好的重構質量和項目收益。那么,移動端架構與網站架構有何不同?網易新聞客戶端的架構演變過程是怎樣的?為何選擇 DDD 思想來指導重構?在 DDD 實踐中應注意哪些方面?

移動端架構與網站架構的區別

傳統的網站架構,通過超文本傳輸協議,使得瀏覽器能夠便捷地將我們想要訪問的頁面展示出來。每個網站由多個頁面組成,這些頁面都屬于 Web Server 的一部分,如圖 1 所示。

圖 1 Website 與 Server 抽象模型

圖 1 Website 與 Server 抽象模型

網站在大多數情況下無需關注離線化,而主要關注負載均衡、高并發和多級緩存等場景,以實時響應大規模流量。

相較之下,移動端 App 需先讓用戶進行安裝,然后才能訪問頁面。移動端的高并發網絡請求等場景通常交由 Server 端處理,而移動端更關注處理用戶交互和界面變化,如圖 2 所示。

圖 2 Application 與 Server 抽象模型

圖 2 Application 與 Server 抽象模型

所以移動端和網站端的核心關注點不同,也就造成了二者在架構上的歷史演進的不同。舉一個簡單的例子,最初起源于 .NET Framework 3.0 的模型 / 視圖 / 視圖模型(MVVM)思想,從 WPF 應用過渡到 http://ASP.NET,用于網頁的開發,后來卻在移動端成為最流行的架構模式之一。

隨著網站端的歷史演進,網頁的工作量和跨平臺的需求增長迅速,使得網站前端開發的重要性日趨明顯,網站端已經抽象為了前端和后端,網站前端通過瀏覽器實現跨平臺,與移動端共同組成了大前端。

目前常見的移動端架構設計模式主要包括關注面向接口編程的 MVP(Model-View-Presenter)、關注數據驅動與雙向綁定的 MVVM(Model-View-ViewModel)、關注表現層分離的 MVC(Mode-View-Controller)和符合領域驅動設計思想(DDD)的 The Clean Architecture 等。

網易新聞客戶端的架構演進歷程

網易新聞客戶端的架構演進主要經歷了四個階段:Static Method、MVP、MVPs 和 VIPER。

為擺脫沉重晦澀的架構模型束縛,網易新聞客戶端團隊將一些軟件設計中的元素抽象為輕松的食品加工中的元素,用蛋糕模型來做示例。

第一階段:Static Method

從最初的設計階段開始,為了簡單地達到代碼的可復用性,新聞客戶端采用了一種 Static Method 的設計方式,將業務邏輯按照業務模塊轉移到一些工具類中,使得開發人員可以用最小成本復用這些業務邏輯。

在 Static Method 的模式中,技術團隊將 View 抽象為一塊蛋糕,蛋糕上需添加奶油、檸檬、櫻桃(Model)等食材。負責輸送材料的加工廠(Static Method)派遣工人(而非廚師)將材料直接運送并擺放在蛋糕上,如圖 3 所示。這樣蛋糕便具備了所有應有的食材成分。然而,食材擺放隨意,使得蛋糕顯得混亂,如果再繼續這樣堆砌食材,它就不再像是一塊蛋糕了。

圖 3 Static Method 蛋糕加工模型

圖 3 Static Method 蛋糕加工模型

因此,隨著時間推移和業務迭代加速,這種失去封裝、多態和繼承的面向對象特性的工具類設計難以應對業務變化。因此,轉向流行的 MVP 模式成為必然趨勢。

第二階段:MVP

傳統的 MVP 模式中,一個 View 由一個 Presenter 管理,在這種模式下產生了代碼復用的難題。

由于 Presenter 與 View 通過接口協議綁定,一個 Presenter 中的業務邏輯通常只能為一個 View 服務。因此,代碼復用性較差,容易產生大量冗余代碼。

Presenter 與 View 為一對一的方式,就像一塊蛋糕(View),指派給一個廚師(Presenter)去制作,但是廚師一個人需要做的事情太多,他需要親自加工食材(Model),再將這些材料一一裝飾在蛋糕上面,如圖 4 所示。如果這時候再告訴他我們的蛋糕還需要添加一些突然增加的裝飾和點綴,他可能會面臨崩潰。

圖 4 MVP 蛋糕加工模型

圖 4 MVP 蛋糕加工模型

第三階段:MVPs

為解決 MVP 代碼復用問題,許多設計方法將 View 與 Presenter 改為多對一模式,即一個 Presenter 可為多個 View 服務,而一個 View 也可被多個 Presenter 控制。這意味著更多 Presenter 參與其中,會產生更多適應不同 View 的接口。

Presenter 與 View 為多對一的方式,就像一塊蛋糕(View),指派給多個廚師(Presenters)在共同加工。而每個廚師可能會處理多塊蛋糕,他們同時還要做好手上的裝飾品(Model),再親自將其放在每個蛋糕上。在這期間,廚師們直接接觸每塊蛋糕時,還加入了很多他們擅長的但是蛋糕不需要的手藝。多個廚師圍著一塊蛋糕轉,蛋糕有了很多他原本不想擁有的東西,而這些廚師們也難以管理,他們直接操控蛋糕,沒人能夠合理控制他們,如圖 5 所示。因此,新聞客戶端逐步過渡到符合 DDD 的 VIPER 模式。

圖 5 MVPs 蛋糕加工模型

圖 5 MVPs 蛋糕加工模型

第四階段:符合 DDD 的 VIPER

在符合領域驅動設計的 VIPER 架構設計模式下,一塊蛋糕(View)只由一個主廚(Presenter)進行裝飾擺放,但是蛋糕上所有的飾品食材,都由這位主廚指派給多個不同的廚師(Interactor)進行加工(Entity)。當這些廚師加工完畢后,再把材料送過來,通知主廚,由主廚親自進行擺放。

那些負責加工的廚師沒有機會再直接接觸到蛋糕,蛋糕只有它原本應有的樣子,變得更加利于加工制作。更美好的是,以往蛋糕需要每個廚師親自配送到它需要被送達的地方,現在廚師只需要打個電話,一切配送工作都將由快遞員(Router)去完成,如圖 6 所示。

圖 6 VIPER 蛋糕加工模型

圖 6 VIPER 蛋糕加工模型

通過這種分工合作的模式,VIPER 架構不僅提高了工作效率,還降低了出錯率。每個環節都有專門的負責人,使得整個流程更加順暢。此外,這種架構還有助于后續的迭代和升級,因為各個模塊之間的耦合度較低,便于獨立開發和更新。

基于 DDD 的短視頻架構優化

以網易新聞客戶端的視頻詳情頁為例,新聞客戶端的視頻詳情頁結構可以抽象為圖 7。初期設計的視頻詳情頁,所承載的業務并不多,界面也較為簡單,Holder、子頁面和適配器等都在 Fragment 類中定義實現。但是隨著短視頻風口的到來,業務加速迭代,視頻的業務需求急劇增加,視頻詳情頁所需要承載的業務也越來越多,Fragment 類從最初的幾百行,急速擴張到兩千多行。基于舊有的視頻詳情頁設計,加入新的業務,使得維護成本變得越來越高,類也變得越來越大,臃腫膨脹的類已經變為了“面條代碼”。

圖 7 視頻詳情頁抽象結構

圖 7 視頻詳情頁抽象結構

基于 DDD 的思想,新聞客戶端實現了一套包含 UseCase 的基礎框架,劃分出了領域模型,由于視頻詳情頁由多 Fragment 組成,技術團隊還加入了共享變量層,使擁有統一生命周期的組件之間能解耦傳遞數據,重構后的視頻詳情頁整體架構如圖 8 所示。

圖 8 視頻詳情頁重構后的架構設計圖

圖 8 視頻詳情頁重構后的架構設計圖

DDD 的選型與實踐

選型背景

新聞客戶端的多數業務模塊在設計初期的時候,多數業務模塊所承載的業務量并不大。但隨著需求的逐漸增加,為了快速迭代,開發人員往往將代碼堆積在一起,導致業務模塊間的邊界變得模糊,耦合度也越來越高。

為了解決這個問題,DDD 的限界上下文為技術團隊提供了明確領域模型邊界和實現解耦的方法。VIPER 是一種符合 DDD 理念的架構模型,盡管最初在 iOS 端流行,但其核心思想與 The Clean Architecture 相似,因此同樣適用于 Android 端,成為一種通用解決方案。

落地難題

在將 DDD 落地的過程中,團隊遇到的比較困難的問題大致是兩方面,一方面在于優化工作流程,另一方面在于轉變編碼思想。

在工作流程方面,傳統需求評審涉及產品經理、項目經理、軟件工程師、UI 交互設計師等,但關注點往往集中在整體業務,事件劃分不夠明確。要推動多個團隊改變評審方式以確定限界上下文的事件風暴,具有一定的困難。因此,開發團隊在編碼階段開始前,進行內部技術評審,邀請準領域專家與開發人員共同分析討論界限上下文。

在編碼思維方面,團隊成員需要接受 DDD 思想,轉變為領域驅動思維。技術團隊組織了一系列相關分享,通過編程中的“隱喻”,讓大家逐步建立對 DDD 的認識,加深理解。

重構效果

在基于 DDD 的架構重構初期,新聞客戶端選擇了視頻詳情、視頻列表和圖集三個業務模塊進行 VIPER 重構,以探索 DDD 的實際應用。

  • 在重構質量上,先確定領域模型,代碼整體解耦符合預期,三個模塊重構后上線均未出現嚴重線上問題。
  • 在項目收益上,一方面,DDD 幫助團隊提高迭代開發效率;另一方面,代碼可維護性大幅提高,模塊錯誤率降低約 50%。

新聞客戶端以半年為周期,統計模塊重構前半年與重構后半年的系統故障率(主要指開發期間產生的問題),如圖 9 所示。數據表明,業務變化頻繁的模塊(如視頻)通過 DDD 獲得的模塊穩定性收益更為顯著。

通過采用 DDD 理念進行架構重構,新聞客戶端在快速迭代和需求變化的過程中,實現了更高的靈活性、可擴展性和代碼質量。通過明確領域模型邊界、優化工作流程和轉變編碼思維,團隊成功應對了落地難題,為客戶端在競爭激烈的市場中奠定了基礎。

圖 9 DDD 重構前后系統故障率統計圖

圖 9 DDD 重構前后系統故障率統計圖

DDD 落地面面觀

自從2003年領域驅動設計(DDD)概念提出以來,它在軟件學術界贏得了廣泛認可。然而,受到國內外開發環境、開發者觀念等多種因素影響,DDD在國內的實際應用并未完全達到預期效果。從2013年開始,微服務架構和中臺化在國內逐漸興起,DDD作為指導原則,有助于明確劃分領域和子領域,因此在企業應用實踐中取得了良好成果,成為國內突然流行的主要原因之一。

對開發團隊而言,實施DDD的關鍵環節是通過事件風暴進行領域分析建模,這對領軍人物的領域素養要求較高,需要承擔領域專家的職責。

針對移動端領域,The Clean Architecture 是目前最適合、符合 DDD 理念的架構模型。Google 官方推出的安卓藍圖項目為 MVP 提供了一套符合 The Clean Architecture 的 MVP-Clean 項目,開發者可以借此展開逐步探索和嘗試。

由于國內外軟件工程師的職業環境和所承受的壓力有所不同,在面對突發業務需求沖擊時,開發者往往只能瘋狂堆疊代碼,導致被迫放棄 DDD 設計。需求變更時,容易出現風險。

在風險加劇的情況下,各種推諉責任的現象頻發,問題本質歸咎于組織結構、環境因素以及邊界劃分不明確。

針對組織和團隊層面,初期無需大規模調整,即可滿足 DDD 轉型需求,并為后續微服務和中臺化建設提供便利。但需注意,改變團隊成員固有的開發思維至關重要,團隊內應定期舉辦 DDD 相關分享,使大家對 DDD 觀念逐漸認同。

總之,在國內軟件開發環境中,實踐 DDD 具有重要意義。遵循 DDD 原則,開發者能夠更好地應對業務需求變化,提高代碼質量和系統穩定性。在組織及團隊層面,推動 DDD 轉型有助于微服務架構和中臺化的實施,提升整體開發效率。為實現這些目標,團隊需共同努力,培養領域素養,明確邊界劃分,并改變固有思維,為 DDD 實踐奠定堅實基礎。

說在最后

DDD架構如何落地,是是非常常見的面試題。

以上的內容,如果大家能對答如流,如數家珍,基本上 面試官會被你 震驚到、吸引到。

在面試之前,建議大家系統化的刷一波 5000頁《尼恩Java面試寶典PDF》,并且在刷題過程中,如果有啥問題,大家可以來 找 40歲老架構師尼恩交流。

最終,讓面試官愛到 “不能自已、口水直流”。offer, 也就來了。

當然,關于DDD,尼恩即將給大家發布一波視頻 《第34章:DDD的學習圣經》, 幫助大家徹底穿透DDD。

尼恩技術圣經系列PDF

  • 《NIO圣經:一次穿透NIO、Selector、Epoll底層原理》
  • 《Docker圣經:大白話說Docker底層原理,6W字實現Docker自由》
  • 《K8S學習圣經:大白話說K8S底層原理,14W字實現K8S自由》
  • 《SpringCloud Alibaba 學習圣經,10萬字實現SpringCloud 自由》
  • 《大數據HBase學習圣經:一本書實現HBase學習自由》
  • 《大數據Flink學習圣經:一本書實現大數據Flink自由》
  • 《響應式圣經:10W字,實現Spring響應式編程自由》
  • 《Go學習圣經:Go語言實現高并發CRUD業務開發》

……完整版尼恩技術圣經PDF集群,請找尼恩領取

《尼恩 架構筆記》《尼恩高并發三部曲》《尼恩Java面試寶典》PDF,請到下面公號【技術自由圈】取↓↓↓

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164128.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164128.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164128.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GEE:梯度提升樹(Gradient Boosting Tree)分類教程(樣本制作、特征添加、訓練、精度、參數優化、貢獻度、統計面積)

作者:CSDN @ _養樂多_ 本文將介紹在Google Earth Engine (GEE)平臺上進行梯度提升樹(Gradient Boosting Tree)分類的方法和代碼,其中包括制作樣本點教程(本地、在線和本地在線混合制作樣本點,合并樣本點等),加入特征變量(各種指數、紋理特征、時間序列特征、物候特征…

OpenStack云計算平臺-啟動一個實例

目錄 一、創建虛擬網絡 ?二、創建m1.nano規格的主機 三、生成一個鍵值對 四、增加安全組規則 ?五、啟動一個實例 1、確定實例選項 2、創建實例 3、使用虛擬控制臺訪問實例 4、驗證能否遠程訪問實例 一、創建虛擬網絡 下面的說明和框圖使用示例IP 地址范圍。你必須依…

Altium Designer學習筆記12

把幾個層理解下: layer名稱功能說明信息Toplayer信號層銅箔層,電氣連接的層Bottomlayer信號層銅箔層,電氣連接的層Internal Planes內層連接地和電源上,一般情況下不布線,是由整片銅膜組成的Mechanical 1機械層電路板機…

String 、StringBuffer 和 StringBuilder 的區別?

String 使用 String 聲明一個字符串的時候,該字符串會存放在堆中的字符串常量池中。因為在java中所有的String 都是以常量表示,且由 final 修飾,因此在線程池中它的線程是安全的 且 不可變的 。每個 String 在被創建后就不再發生任何變化。 …

mysql按年、季度、月,統計

以下是按年、按季度和按月統計SQL查詢語句: 按年統計: SELECTds.checker,YEAR(ds.create_time) AS settleYear,SUM(ds.quantity) AS quantity,SUM(ds.approval_price) AS approvalPrice FROMdata_settle ds WHEREds.delete_flag 0AND ds.approval_sta…

漏洞盒子公益SRC

漏洞盒子公益SRC,小小地記錄一下第一個月的成果

數據中臺建設方法論

1、數倉的概念和了解--業務的痛點 產生的痛點:數據資產比較模糊、數據的質量比較低、重復建設、代碼的耦合性比較強。 2、數據倉庫中的常見的模型: 1、心型模型:中間是一張事實表,周圍都是維度表。 對于心型模型的主要的特點&a…

面向未來的自動化:擁抱機器人即服務(RaaS)

01. RaaS是什么? 對于希望實現業務流程自動化的公司來說,機器人通常是一筆巨大的資本支出。由于機器人非常昂貴,公司可能需要等待數年才能看到投資回報。正是由于這一現實,許多較小的組織無法投資機器人。 但一些機器人公司正在采…

算法通關村第十二關-青銅挑戰字符串

大家好我是蘇麟 , 今天帶來字符串專題 . 轉換成小寫字母 描述 : 給你一個字符串 s ,將該字符串中的大寫字母轉換成相同的小寫字母,返回新的字符串。 題目 : LeetCode 709.轉換成小寫字母 : 709. 轉換成小寫字母 分析 : 這個題可以先遍歷整個字符串…

Mybatis和MybatisPlus:數據庫操作工具的對比

目錄 什么是mybatis 什么是mybatisplus MyBatis-Plus:為簡化數據庫操作而生的強大工具 一、MyBatis-Plus的背景和概述 二、MyBatis-Plus的主要特點 三、如何使用MyBatis-Plus mybatis-Plus的優勢 什么是Hibernate Hibernate:Java開發者的數據持久…

光譜圖像超分 Benchmark

光譜圖像超分 Benchmark 文章目錄 光譜圖像超分 Benchmark0. pioneer工作及綜述基于深度學習的高光譜多光譜融合(updating)1. 空間光譜圖像超分 (to be updated)2. 高分辨率多光譜圖像超分(to be updated)3…

重生之我是一名程序員 39 ——C語言題目之青蛙跳臺階

哈嘍啊大家晚上好!今天給大家帶來的是C語言經典題目之青蛙跳臺階。青蛙跳臺階是一個數學問題,也是一個經典的遞歸問題。假設一只青蛙要跳上一個n級臺階,它可以每次跳1級臺階或2級臺階。問:青蛙跳上這個n級臺階總共有多少種不同的跳…

AMESim|學習記錄

此文記錄AMESim學習過程中的各種情況。 目錄 01 王佳. AUV 浮力調節系統設計及控制策略研究[D]. 天津大學, 2017.01 王佳. AUV 浮力調節系統設計及控制策略研究[D]. 天津大學, 2017. 01 王佳. AUV 浮力調節系統設計及控制策略研究[D]. 天津大學, 2017. 開始步入正文 01 王佳.…

【Leetcode合集】14. 最長公共前綴

14. 最長公共前綴 14. 最長公共前綴 代碼倉庫地址: https://github.com/slience-me/Leetcode 個人博客 :https://slienceme.xyz 編寫一個函數來查找字符串數組中的最長公共前綴。 如果不存在公共前綴,返回空字符串 ""。 示例 …

【UE】用樣條線實現測距功能(下)

目錄 效果 步驟 一、實現多次測距功能 二、通過控件藍圖來進行測距 在上一篇(【UE】用樣條線實現測距功能(上))文章基礎上繼續實現多次測距和清除功能。 效果 步驟 一、實現多次測距功能 打開藍圖“BP_Spline”&#xff0c…

cherry pick的使用

https://blog.csdn.net/weixin_55229531/article/details/128726872

SPS簡單對應分析

前言: 本專欄參考教材為《SPSS22.0從入門到精通》,由于軟件版本原因,部分內容有所改變,為適應軟件版本的變化,特此創作此專欄便于大家學習。本專欄使用軟件為:SPSS25.0 本專欄所有的數據文件請點擊此鏈接下…

Git如何修改提交(commit)用戶名稱(user.name)和郵箱(user.email)

Git用戶名 Git查看用戶名 git config user.name修改Git提交用戶名 修改全局Git用戶名 git config --global user.name "xx" 修改當前服務/項目Git用戶名 git config user.name "xx"如果出現以下錯誤,解決方案如下: 錯誤案例&am…

量子計算概述

目錄 1.量子計算介紹 2.量子計算應用 3.量子計算研究機構 1.量子計算介紹 量子計算是一種遵循量子力學規律調控量子信息單元進行計算的新型計算模式。經典計算使用2進制進行運算,但2進制只有0和1兩種狀態,而量子計算除了包含0和1兩種狀…