如何开始DDD(完)
連續(xù)寫了兩篇文章,這一篇我想是序的完結(jié)篇了。結(jié)合用戶注冊的例子再將他簡單豐富一下。在這里只添加一個簡單需求,就是用戶注冊成功后給用戶發(fā)一封郵件。補充一下之前的代碼
public class DomainService {public void Register(User user){if (_userRepository.IsLoginIdExist(user.LoginId)) {throw new Exception("用戶名已存在");}_userRepository.Add(user);MailService.Send(user.Email, "郵件內(nèi)容");} }上面的代碼是存在一點問題的,了解DDD的人都知道,此時user并沒有持久化或者持久化是否成功是不確定的,假設(shè)此時持久化user失敗了,但郵件卻發(fā)送出去了,這顯然不是我們想要的結(jié)果。怎么辦?我能想到的是兩種辦法。
第一種:創(chuàng)建一個發(fā)送郵件的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, "郵件內(nèi)容"));} }在添加用戶的時候同時添加一條郵件消息,這樣他們將會在同一個事務(wù)中,要么一起成功,要么一起失敗。最后再設(shè)計個計劃任務(wù),從郵件記錄表中取出記錄依次發(fā)送郵件,發(fā)送成功的可以標(biāo)記一下,至于怎么做就不細講了。
?
第二種:就是這一篇我要介紹的使用事件。
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.. 發(fā)送郵件 } }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; } }這樣用戶注冊會產(chǎn)生一個事件。持久化成功后,會將事件發(fā)布出去,這樣EventBus就會監(jiān)聽并處理此事件。上面的代碼可能閱讀理解起來不是那么的直白,具體的實現(xiàn)起來也并非就這么簡單,只是提出一種方法。具體實現(xiàn)我的開源代碼里也有相關(guān)例子https://github.com/imyounghan/thinknet
?
總結(jié)
以上三篇文章我也主要是從寫代碼的角度去介紹如何DDD,強調(diào)一下我不是在教你如何寫代碼,只是為了展示用DDD如何實現(xiàn),領(lǐng)域里的模型更應(yīng)該能表達業(yè)務(wù),他的價值更并不僅于此。而且以上的描述不一定完全正確,也不是告訴你一定要如何做,這也需要你自己的思考,如果有不對的地方歡迎你的指正,畢竟DDD我在學(xué)習(xí)過程中,也能從中受益。
如果我們過多的精力花在如何寫代碼上,可能是收集的工具類庫還不強大,或者是還沒有一個能夠方便快捷開發(fā)的框架,當(dāng)然一個好的框架帶來的好處會很多。一個框架終究是有辦法和技術(shù)能力去實現(xiàn)完成的,但是如何分析和理解業(yè)務(wù),然后從中挖掘出便于閱讀和表達業(yè)務(wù)的模型確定一件不容易的事情,他并不是通過某種技術(shù)辦法就能實現(xiàn)的。所以我個人覺得設(shè)計模型,劃分界限上下文是需要不斷的積累領(lǐng)域業(yè)務(wù)知識才能做到的。
“領(lǐng)域驅(qū)動設(shè)計”和“實現(xiàn)領(lǐng)域驅(qū)動”這兩本書應(yīng)該是最經(jīng)典的了,知識點也很多,閱讀此書你會得到更多的收獲!
?
轉(zhuǎn)載于:https://www.cnblogs.com/younghan/p/3892598.html
總結(jié)
以上是生活随笔為你收集整理的如何开始DDD(完)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈 trie树 及其实现
- 下一篇: Html——小米商城网页实战(一)