如何開始DDD(完)

連續寫了兩篇文章,這一篇我想是序的完結篇了。結合用戶注冊的例子再將他簡單豐富一下。在這里只添加一個簡單需求,就是用戶注冊成功后給用戶發一封郵件。補充一下之前的代碼

public class DomainService
{public void Register(User user){if (_userRepository.IsLoginIdExist(user.LoginId)) {throw new Exception("用戶名已存在");}_userRepository.Add(user);MailService.Send(user.Email, "郵件內容");}
}

上面的代碼是存在一點問題的,了解DDD的人都知道,此時user并沒有持久化或者持久化是否成功是不確定的,假設此時持久化user失敗了,但郵件卻發送出去了,這顯然不是我們想要的結果。怎么辦?我能想到的是兩種辦法。

第一種:創建一個發送郵件的model。

public class MailMessage
{public MailMessage(string receiver, string content){this.Receiver = receiver;this.Content = content;}public string Receiver { get; private set; }public string Content { get; private set; }
}public class DomainService
{public void Register(User user){if (_userRepository.IsLoginIdExist(user.LoginId)) {throw new Exception("用戶名已存在");}_userRepository.Add(user);_mailRepository.Add(new MailMessage(user.Email, "郵件內容"));}
}

在添加用戶的時候同時添加一條郵件消息,這樣他們將會在同一個事務中,要么一起成功,要么一起失敗。最后再設計個計劃任務,從郵件記錄表中取出記錄依次發送郵件,發送成功的可以標記一下,至于怎么做就不細講了。

?

第二種:就是這一篇我要介紹的使用事件。

public class UserRegistered : IEvent
{public UserRegistered(string name, string email){this.Name = name;this.Email = email;}public string Name { get; private set; }public string Email { get; private set; }
}public class UserRegisteredHandler : IEventHandler<UserRegistered>
{public void Handle(UserRegistered @event){//TODO.. 發送郵件 
    }
}public class User : IEventPublisher
{private readonly IList<IEvent> _uncommittedEvents = new List<IEvent>();IEnumerable<IEvent> IEventPublisher.Events{get { return this._uncommittedEvents; }}public User(string name, string password, string email){this.Name = name;this.Password = password;this.Email = email;_uncommittedEvents.Add(new UserRegistered(name, email));}public string Name { get; private set; }public string Password { get; private set; }public string Email { get; private set; }
}

這樣用戶注冊會產生一個事件。持久化成功后,會將事件發布出去,這樣EventBus就會監聽并處理此事件。上面的代碼可能閱讀理解起來不是那么的直白,具體的實現起來也并非就這么簡單,只是提出一種方法。具體實現我的開源代碼里也有相關例子https://github.com/imyounghan/thinknet

?

總結

以上三篇文章我也主要是從寫代碼的角度去介紹如何DDD,強調一下我不是在教你如何寫代碼,只是為了展示用DDD如何實現,領域里的模型更應該能表達業務,他的價值更并不僅于此。而且以上的描述不一定完全正確,也不是告訴你一定要如何做,這也需要你自己的思考,如果有不對的地方歡迎你的指正,畢竟DDD我在學習過程中,也能從中受益。

如果我們過多的精力花在如何寫代碼上,可能是收集的工具類庫還不強大,或者是還沒有一個能夠方便快捷開發的框架,當然一個好的框架帶來的好處會很多。一個框架終究是有辦法和技術能力去實現完成的,但是如何分析和理解業務,然后從中挖掘出便于閱讀和表達業務的模型確定一件不容易的事情,他并不是通過某種技術辦法就能實現的。所以我個人覺得設計模型,劃分界限上下文是需要不斷的積累領域業務知識才能做到的。

“領域驅動設計”和“實現領域驅動”這兩本書應該是最經典的了,知識點也很多,閱讀此書你會得到更多的收獲!

?

轉載于:https://www.cnblogs.com/younghan/p/3892598.html

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

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

相關文章

git pull 報錯:Untracked Fles Preventing Merge

場景 使用 git pull 命令更新報錯解決 找到對應的文件刪除后重新打開項目。

關于string,我今天科普的

今天下午朋友討論組上討論一個關于string的問題&#xff0c;問題是這樣的&#xff0c;string a"aaa";string ba;a"bbb",為什么測試b的值不改變&#xff1f;之前我看過一個文章&#xff0c;知道肯定不相等&#xff0c;因為引用地址的一系列問題&#xff0c;…

git pull 報錯:The following untracked working tree files would be overwritten by merge

場景 使用 git pull 命令更新報錯 Updating d652d1c..fa05549 error: The following untracked working tree files would be overwritten by merge:.idea/encodings.xmlPlease move or remove them before you can merge. Aborting 解決 使用 git clean -d -fx 命令即可。

SpringBoot 配置多數據源

項目Git地址&#xff1a;SpringBoot 配置多數據源&#xff1a;Jacob-multi-data-source 準備工作 準備兩個數據庫(此模塊中兩個數據庫一個為本地 一個為遠程&#xff0c;本地為主&#xff0c;遠程為從)。然后建表。 #本地庫 CREATE TABLE username (id bigint(11) NOT NULL AUT…

HDU 2912

直線關于球的多次反射&#xff0c;求最后一次反射點 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath>using namespace std; const double inf1e10; const double eps1e-8; struct point {doub…

EMVTag系列3《持卡人基本信息數據》

9F61 持卡人證件號 L&#xff1a;2–26 R&#xff08;需求&#xff09;&#xff1a;數據應存在&#xff0c;在讀應用數據過程中&#xff0c;終端不檢查&#xff1b; (PBOC2.0第五部分中規定)芯片中持卡人姓名 5F20與持卡人姓名擴展9F0B只能使用一個&#xff0c;另一個必須不…

BindingException: Parameter 'XXX' not found. Available parameters are [collection, list]

應業務需求&#xff0c;需要使用到MQ進行數據上傳和下發。傳遞格式為JSON,服務那邊下發JSON數組&#xff0c;接收端將JSON數組轉換成List集合&#xff0c;調用Mybatis-plus批量添加saveBatch()。提示字段未找到... org.apache.ibatis.exceptions.PersistenceException: ### Er…

JDK 8 新特性 之 default關鍵字

前言 Jdk1.8之前的接口中只聲明方法&#xff0c;方法具體實現應在子類中進行。Jdk1.8打破了這樣的用法&#xff1a;接口中可以實現具體的方法體&#xff0c;只需要加上關鍵字static或者default修飾即可。 default關鍵字 public interface UserService {//自定義方法void getUse…

headroom.js插件使用方法

1.什么是headroom.js&#xff1f; headroom是用純Javascript寫的插件&#xff0c;用來隱藏和展示頁面元素&#xff0c;從而為頁面留下更多空間。比如使用headroom能使導航欄當頁面下滾時消失&#xff0c;當頁面上滾時候又出現。&#xff08;查看效果&#xff09; 2.工作原理 通…

JDK 8 新特性 之 方法引用

概述 方法引用&#xff1a;當要傳遞給Lambda體的操作&#xff0c;已經有實現的方法了&#xff0c;就可以使用方法引用方法引用&#xff1a;在Lambda的基礎上進一步的簡化。換句話說&#xff0c;方法引用就是Lambda表達式&#xff0c;也就是函數式接口的一個實例&#xff0c;通過…

項目記錄:springmvc forward redirect 問題

RequestMapping("/redirect")public String redirect(RedirectAttributes redirectAttributes){redirectAttributes.addFlashAttribute("test", "testdata"); //專供此種情況下使用。return "redirect:read";} 注意&#xff1a;此種情…

JDK 8 新特性 之 Lambda表達式

前言 Lambda 表達式&#xff0c;也可稱為閉包&#xff0c;它是推動 Java 8 發布的最重要新特性。Lambda 允許把函數作為參數傳遞進方法中。使用 Lambda 表達式可以使代碼變的更加簡潔緊湊。lambda表達式的重要特征: 可選類型聲明&#xff1a;不需要聲明參數類型&#xff0c;編譯…

開源組件DocX導出Word

1、使用Docx替換Word模板里書簽里內容的一個方法 using Novacode;public class ExportWord{/// <summary>/// 導出word/// </summary>/// <param name"lBookMarks">書簽數據源</param>/// <param name"sTemplatePath">導出W…

JDK 8 新特性 之 Strams簡單使用

概述 Java 8 API添加了一個新的抽象稱為流Stream&#xff0c;可以讓你以一種聲明的方式處理數據。 Stream 使用一種類似用 SQL 語句從數據庫查詢數據的直觀方式來提供一種對 Java 集合運算和表達的高階抽象。 Stream API可以極大提供Java程序員的生產力&#xff0c;讓程序員寫出…

Cannot open include file: jni.h: No such file or directory解決方法

在此運行Visual Studio 2012 項目時出現 #include <stdio.h> #include <jni.h> int main() { printf("Hello World"); } But when I try to build, I get the following error - 1>c:testtest.cpp(2) : fatal error C1083: Cannot open include file:…

JDK 8 新特性 之 函數接口

函數接口 定義:接口中只有唯一的一個抽象方法&#xff0c;該接口就稱之為函數接口。 //函數接口 public interface FunctionInterface1 {//1、只有一個方法的接口&#xff0c;默認稱之為函數接口void get(); }//非函數接口 public interface FunctionInterface2 {void get1();v…

微服務之基礎知識

什么是微服務架構 微服務是系統架構上的一種設計風格&#xff0c; 它的主旨是將一個原本獨立的系統拆分成多個小型服務&#xff0c;這些小型服務都在各自獨立的進程中運行&#xff0c;服務之間通過基于HTTP的RESTful API進行通信協作。 被拆分成的每一個小型服務都圍繞著系統中…

LightOj 1078 Basic Math

思路&#xff1a; 設輸入的兩個數分別為n和a,每一次所得到的數為update&#xff1a; 開始updatea,依次update分別為update*10a,這樣數據會超出范圍&#xff0c;則update每次為update(update*10a)%n即可&#xff0c; 如果update0,跳出循環&#xff1b; 只需證明&#xff1a;(upd…

還是俄羅斯方塊之android版

前面的&#xff0c;口水話 請直接跳過。 雖然現在不比以前了 也沒多少人氣了&#xff0c;放到首頁 都不到幾百的點擊量。也許博客園整體水平也是在往水的方向發展。不談那些了&#xff0c;哥也曾經輝煌過 有過一天上千的點擊量 &#xff0c;哥也曾經有過粉絲&#xff0c;被小妹…

Integer 值判斷相等

Integer 值判斷相等 案例&#xff1a; public class Test {public static void main(String[] args) {Integer a 127;Integer b 127;System.out.println("a b :" (a b));System.out.println("a.equals(b):"a.equals(b));String x "127";Str…