如何一步一步用DDD設計一個電商網站(三)—— 初涉核心域

来源:http://www.cnblogs.com/Zachary-Fan/archive/2016/11/07/6036729.html
-Advertisement-
Play Games

一、前言 結合我們本次系列的第一篇博文中提到的上下文映射圖(傳送門:如何一步一步用DDD設計一個電商網站(一)—— 先理解核心概念),得知我們這個電商網站的核心域就是銷售子域。因為電子商務是以信息網路技術為手段,以商品交換為中心的商務活動,一個好的核心域設計可以大大提升企業的競爭力和對市場變化的相應 ...


一、前言

    結合我們本次系列的第一篇博文中提到的上下文映射圖(傳送門:如何一步一步用DDD設計一個電商網站(一)—— 先理解核心概念),得知我們這個電商網站的核心域就是銷售子域。因為電子商務是以信息網路技術為手段,以商品交換為中心的商務活動,一個好的核心域設計可以大大提升企業的競爭力和對市場變化的相應速度。

 那麼我們開始設計領域對象。對於設計領域對象的基本概念不瞭解的可以先閱讀我的該系列第二篇文章(傳送門:如何一步一步用DDD設計一個電商網站(二)—— 項目架構)。

 

二、定義幾個基類

    我相信我們大部分人會以如下的方式去存放我們定義的基類,見圖1。

              【圖1】

    這是一種比較常規的技術分層思維方式產生的結果,在某些項目文件中或多或少有那麼幾個"Base"、"Core"、"Common"等的文件夾存放著一些通用的類,它們起著對當前項目中類的抽象、實現通用性支撐性功能的作用。然而在DDD中這些都應屬於基礎設施層的事情,這樣能夠保證其他層專註於自身的職責,不會把本應內聚的東西泄露到這些類中。如我們當前的領域層就專註於領域建模,裡面的概念全部與通用語言相關。說乾就乾,搬到基礎設施層去,再取個能表達出一致概念的名字的模塊存放,如圖2。

              【圖2】

三、核心域(銷售子域)中有什麼

    “銷售”用通俗的話講就是“把商品賣給用戶”,這幾個字中就已經凸顯出幾個概念:“商品”,“用戶”,“賣”。以下就是”商品“和”用戶“的代碼實現:

                【圖3】

              【圖4】

    我相信有許多人會以圖3和圖4的方式定義我們的商品和用戶,乍一看的確符合對商品、用戶概念的獨立的理解。但在DDD中有不同的限界上下文,每個限界上下文專註處理自身的業務,多個限界上下文之間是以協作的方式工作。保證多個限界上下文之間的良好協作關係的方式是提高自治性。提高自治性的方式又有很多,技術方面如領域事件、消息隊列、事件源等,這裡暫時不展開描述。從代碼層面來看,建模的時候只獲取對當前上下文業務處理剛剛好大小的數據,也可以提高當前項目的自治性。

    根據我們劃分的上下文映射圖,用戶和商品是屬於另外的上下文的,那麼在這裡我們都應該建模為值對象,因為我們是無法直接修改這些對象的內部屬性的。另外,在上面2個圖中,獲取其他上下文中的資源時,我們作為客戶方基本上是不會原封不動的消費服務方提供的數據的。比如這裡面的Product.PermitNo(批文號),在大部分行業里,它與銷售商品沒什麼關係。再如User.BlockedBalance(凍結餘額),在銷售的過程中,只需要知道用戶有多少可用餘額就好了。這個思路總結一下就是,從業務角度我們不求大而全,只求剛好滿足當前業務即可,但是當業務發生變化的時候我們的領域模型也要及時反映出調整後的通用語言概念。得到修改後的模型:

                  【圖5】

                  【圖6】

    對了,不管是值對象還是實體和聚合,習慣在構造函數中的做好守衛驗證,有利於表達出什麼樣的領域對象是合法的。

 

四、更好的存活於分散式背景下

 在某些背景下一個限界上下文是作為獨立的服務對外提供API進行訪問的,特別在電商行業,分散式系統的構建是個普遍情況,方式也多元化,各種RPC框架、Restful等技術選型,SOA、微服務等實現理念層出不窮。如何最大化的降低技術變更和業務變化導致的上下文劃分調整的影響,也是我們要考慮的重要問題。

 對於我們.Net開發人員來說,在分散式場景下用的最多的方式無非是WebAPI和WCF了。這種方式也就是在第一篇文章中所提到的發佈語言和開放主機服務,那麼對於客戶端來說需要做好防腐層(第一篇文章中有提到)的工作,好避免外部上下文的概念侵入到自身的領域概念中。一個普遍的防腐層實現時序圖,其中真正負責防腐層工作的是XXXAdapter和XXXTranslator,如下(摘自[Vaughn Vernon]《實現領域驅動設計》):

                        【圖7】

我們這裡實現的相關類如下圖所示定義:

                  【圖8】

  其中1存放著訪問遠程資源的介面定義,2是其實現方式。這樣設計的好處是,對於領域層的建模隱藏了數據獲取的實現細節。並且當我們實際開發的時候可能由於需要配合服務方還未準備好,但是這絲毫不影響我們的開發工作,我們可以定義個Mock類來實現這裡的IRemoteServices中的介面,就可以順利地進行開發工作。

  其中ProductAdapter、UserAdapter分別負責請求商品上下文和用戶上下文並取得原始結果,ProductTranslator、UserTranslator則是通過解析原始結果,轉換為我方上下文中需要的領域模型概念。以下則是核心部分的實現:

                  【圖9】

                   【圖10】

 

五、結語  本來打算想把整個“把商品賣給用戶”過程講完,但是發現這樣篇幅太長,所以這次就先到這裡,先把其中的2個主體整個設計過程給弄明白了,接下去再講“賣”這個行為該如何設計。謝謝各位看官:)  本文的源碼地址:https://github.com/ZacharyFan/DDDDemo,註意其中的Restful請求地址和Json解析類為假實現,僅為了用於支持本文的表述。

 

    

 

作者:Zachary_Fan
出處:http://www.cnblogs.com/Zachary-Fan/p/6036729.html

    


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.1概述 運用共用技術有效地支持大量細粒度的對象。這就是享元模式的定義。 一個類中的成員變數表明該類所創建對象所具有的屬性,在某些程式設計中可能用一個類創建若幹個對象,但是發現這些對象的一個共同特點是它們有一部分屬性的取值必須是完全相同的。 例如,一個Car類,其類圖如下圖一所示: 圖一:Car類 ...
  • 概念: Java中單例模式是一種常見的設計模式,單例模式的寫法有好幾種,這裡主要介紹三種:懶漢式單例、餓漢式單例、登記式單例。 單例模式有以下特點: 1、單例類只能有一個實例。 2、單例類必須自己創建自己的唯一實例。 3、單例類必須給所有其他對象提供這一實例。 單例模式確保某個類只有一個實例,而且自 ...
  • 需要導入基本的包hibernate下的bin下的required和同bin下optional里的c3p0包下的所有jar文件,當然要導入mysql的驅動包了。下麵需要註意的是hibernate的版本就好了。 <?xml version="1.0" encoding="UTF-8"?> <!DOCTY ...
  • 這個設計模式,說真的,我還沒讀懂,讀懂的兄弟可以留言幫我解釋一下,我需要 慢慢的研究 這 中模式的好處,和優點,先附上我的代碼 看完之後,我凌亂了 ...
  • 為什麼寫這個系列文章? 1)行業趨勢:15年說過,隨著互聯網架構的普及,軟體複雜度的提升,架構師職位會在未來五年,迅速發展。誰掌握了架構,誰就掌握了軟體技術的核心。 2)15年承諾:起源於大型網站架構,計劃寫完大型網站架構系列,開始《一步一步學架構系列》(目前改名為:從零開始學架構系列) 3)個人感 ...
  • 概述 集群和分散式都是從集中式 進化 而來的。分散式和集群會相互合作的,同時的集群和分散式。在這裡重點說說集群 集群是什麼? 集群能提高單位時間內處理的任務數量,提升伺服器性能 有多台伺服器去處理任務,但是 每個任務都是由一臺伺服器獨立完成的 分散式是什麼? 分散式能縮短單個任務處理的時間 跟集群一 ...
  • 1. 微軟基礎類庫(英語:Microsoft Foundation Classes,簡稱MFC)是一個微軟公司提供的類庫(class libraries),以C++類的形式封裝了Windows API,並且包含一個應用程式框架,以減少應用程式開發人員的工作量。其中包含的類包含大量Windows句柄封 ...
  • 問題:兩張表互為外鍵約束,刪除任何一張表都會出錯 解決方法:臨時關閉檢查 語法:set @@foreign_key_checks=OFF; OK,然後就可以推倒你親手種的果了,各種姿勢drop ps:資料庫設計寧可多花點兒時間,準沒錯。 walker花了一周的時間寫個小項目練手,沒想到今天突然發現底 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...