领域驱动设计学习笔记(一 事件总线)

xiaoxiao2021-02-28  16

领域驱动设计学习笔记(一 事件总线)

何为领域驱动设计?

2004年著名建模专家Eric Evans发表了他最具影响力的书籍:《Domain-Driven Design: Tackling Complexity in the Heart of Software》(中文译名:领域驱动设计:软件核心复杂性应对之道),书中提出了领域驱动设计(简称 DDD)的概念。

  领域驱动设计事实上是针对OOAD的一个扩展和延伸,DDD基于面向对象分析与设计技术,对技术架构进行了分层规划,同时对每个类进行了策略和类型的划分。

  领域模型是领域驱动的核心。采用DDD的设计思想,业务逻辑不再集中在几个大型的类上,而是由大量相对小的领域对象(类)组成,这些类具备自己的状态和行为,每个类是相对完整的独立体,并与现实领域的业务对象映射。领域模型就是由这样许多的细粒度的类组成。基于领域驱动的设计,保证了系统的可维护性、扩展性和复用性,在处理复杂业务逻辑方面有着先天的优势。

摘自:http://kb.cnblogs.com/page/112298/

领域模型的种类? 失血模型:模型仅仅包含数据的定义和getter/setter方法,业务逻辑和应用逻辑都放到服务层中。这种类在Java中叫POJO,在.NET中叫POCO。贫血模型:贫血模型中包含了一些业务逻辑,但不包含依赖持久层的业务逻辑。这部分依赖于持久层的业务逻辑将会放到服务层中。可以看出,贫血模型中的领域对象是不依赖于持久层的。充血模型:充血模型中包含了所有的业务逻辑,包括依赖于持久层的业务逻辑。所以,使用充血模型的领域层是依赖于持久层,简单表示就是 UI层->服务层->领域层<->持久层。胀血模型:胀血模型就是把和业务逻辑不想关的其他应用逻辑(如授权、事务等)都放到领域模型中。我感觉胀血模型反而是另外一种的失血模型,因为服务层消失了,领域层干了服务层的事,到头来还是什么都没变。 领域事件和事件总线

总管对象(事件总线)   EventBus

主要职责是管理领域模型的所有事件,通过Dictionary<Type,List<object>> _dicEventHandler=new Dictionary<Type, List<object>>();主要包括

Subscribe订阅相关的领域对象事件Publish 触发所有在事件总线上的领域对象事件句柄 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyDDD { /// <summary> /// 事件总线 /// </summary> public class EventBus { /// <summary> /// 事件总线对象 /// </summary> private static EventBus _eventBus=null; /// <summary> /// 领域模型事件句柄字典,用于存储领域模型的句柄 /// </summary> private static Dictionary<Type,List<object>> _dicEventHandler=new Dictionary<Type, List<object>>(); /// <summary> /// 附加领域模型处理句柄时,锁住 /// </summary> private readonly object _syncObject = new object(); /// <summary> /// 单例事件总线 /// </summary> public static EventBus Instance { get { return _eventBus ?? (_eventBus=new EventBus()); } } private readonly Func<object, object, bool> _eventHandlerEquals = (o1, o2) => { return true; }; #region 订阅事件 public void Subscribe<TEvent>(IEventHandler<TEvent> eventHandler) where TEvent : IEvent { //同步锁 lock (_syncObject) { //获取领域模型的类型 var eventType = typeof (TEvent); //如果此领域类型在事件总线中已注册过 if (_dicEventHandler.ContainsKey(eventType)) { var handlers = _dicEventHandler[eventType]; if (handlers != null) { handlers.Add(eventHandler); } else { handlers=new List<object> { eventHandler }; } } else { _dicEventHandler.Add(eventType, new List<object> { eventHandler }); } } } #endregion #region 宣布事件 public void Publish<TEvent>(TEvent tEvent, Action<TEvent, bool, Exception> callback) where TEvent:IEvent { var eventType = typeof (TEvent); if (_dicEventHandler.ContainsKey(eventType) && _dicEventHandler[eventType] != null && _dicEventHandler[eventType].Count > 0) { var handlers = _dicEventHandler[eventType]; try { foreach (var handler in handlers) { var eventHandler = handler as IEventHandler<TEvent>; eventHandler.Handle(tEvent); callback(tEvent, true, null); } } catch (Exception ex) { callback(tEvent, false, ex); } } else { callback(tEvent, false,null); } } #endregion } }

 

 

领域对象

领域对象通过实现IEvent接口,标记此领域对象可以往事件总线中订阅与自己相关的领域对象事件。

用户注册领域对象

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyDDD { /// <summary> /// 领域模型对象 /// </summary> public class UserGenerator:IEvent { /// <summary> /// 用户Id /// </summary> public Guid UserId { get; set; } } } 领域对象事件句柄

领域对象事件句柄是领域对象发生变化时,通知EventBus触发所有的事件句柄

 

public void Publish<TEvent>(TEvent tEvent, Action<TEvent, bool, Exception> callback) where TEvent:IEvent 用户注册发送Email的事件句柄 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyDDD { /// <summary> /// /// </summary> public class UserAddedEventHandlerSendEmail : IEventHandler<UserGenerator> { public void Handle(UserGenerator tEvent) { Console.WriteLine(string.Format("{0}的邮件已发送", tEvent.UserId)); } } }

 

  例子说明:当用户注册完成后,通知EventBus,由EventBus触发相应操作,发送Email或者其他操作。 这样的好处用户注册是主业务,其他属于拓展,增加或减少需求,只需要往EventBus上订阅或取消事件即可。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyDDD { class Program { static void Main(string[] args) { EventBus.Instance.Subscribe(new UserAddedEventHandlerSendEmail()); var userGenerator = new UserGenerator{UserId = Guid.NewGuid()}; Console.WriteLine("{0}注册成功",userGenerator.UserId); EventBus.Instance.Publish(userGenerator, CallBack); Console.ReadKey(); } public static void CallBack(UserGenerator userGenerator, bool result, Exception ex) { } } }

http://www.cnblogs.com/cainiaoguoshi/p/4696965.html

 

 

转载请注明原文地址: https://www.6miu.com/read-1249998.html

最新回复(0)