java ddd 事件总线_DDD事件总线的实现

基本思路:

(1)       在事件总线内部维护着一个事件与事件处理程序相映射的字典。

(2)       利用反射,事件总线会将实现了IEventHandler的处理程序与相应事件关联到一起,相当于实现了事件处理程序对事件的订阅。

(3)       当发布事件时,事件总线会从字典中找出相应的事件处理程序,然后利用反射去调用事件处理程序中的方法。

核心类(事件总线类)

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Linq;4 usingSystem.Reflection;5

6

7 namespaceFramework.EventBus8 {9 public classEventBus10 {11

12 private static EventBus _eventBus = null;13

14 private static Dictionary> _eventMapping = new Dictionary>(); //在这个字典中,key存储的是事件,而value中存储的是事件处理程序

15

16

17 privateEventBus() { }18 ///

19 ///单例20 ///

21 ///

22 public staticEventBus Instance()23 {24 if (_eventBus == null)25 {26 _eventBus = newEventBus();27 MapEvent2Handler();28 }29 return_eventBus;30 }31

32

33

34 ///

35 ///发布36 ///这里没有用到队列之类的东西,使用的是直接调用的方式37 ///

38 ///

39 public voidPublish(BaseEvent eventData)40 {41 //找出这个事件对应的处理者

42 Type eventType =eventData.GetType();43

44 if (_eventMapping.ContainsKey(eventType) == true)45 {46 foreach (Type item in_eventMapping[eventType])47 {48 MethodInfo mi = item.GetMethod("Handle");49 if (mi != null)50 {51 object o =Activator.CreateInstance(item);52 mi.Invoke(o, new object[] { eventData });53 }54 }55

56 }57 }58

59

60

61

62

63 ///

64 ///将事件与事件处理程序映射到一起65 ///使用元数据来进行注册66 ///

67 static voidMapEvent2Handler()68 {69 Assembly assembly =Assembly.GetExecutingAssembly();70 Type[] types =assembly.GetTypes();71

72 foreach (Type type intypes)73 {74 Type handlerInterfaceType = type.GetInterface("IEventHandler`1"); //事件处理者

75

76 if (handlerInterfaceType != null) //若是事件处理者,则以其泛型参数为key,事件处理者的集合为value添加到映射中

77 {78 Type eventType = handlerInterfaceType.GetGenericArguments()[0]; //这里只有一个79 //查找是否存在key

80 if(_eventMapping.Keys.Contains(eventType))81 {82 List handlerTypes =_eventMapping[eventType];83 handlerTypes.Add(type);84 _eventMapping[eventType] =handlerTypes;85 }86 else //存在则添加

87 {88 List handlerTypes = new List();89 handlerTypes.Add(type);90 _eventMapping.Add(eventType, handlerTypes);91 }92 }93 }94 }95

96 }97 }

核心类(事件基类)

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Linq;4 usingSystem.Text;5

6 namespaceFramework.EventBus7 {8 public classBaseEvent9 {10

11 ///

12 ///事件发生的时间13 ///

14 public DateTime EventTime { get; set; }15

16 ///

17 ///事件源18 ///

19 public object EventSource { get; set; }20

21

22 }23 }

核心类(事件处理程序接口)

1 namespaceFramework.EventBus2 {3 public interface IEventHandler

4 whereT : BaseEvent5 {6 voidHandle(T eventData);7 }8 }

使用方法

实现接口IEventHandler

1 usingSystem;2 usingSystem;3 usingSystem.Collections.Generic;4 usingSystem.Linq;5 usingSystem.Text;6

7

8 namespaceFramework.EventBus9 {10 ///

11 ///实现了IEventHandler接口,就是订阅了OrderAddedEvent事件12 ///

13 public class OrderAddedEventHandler1 : IEventHandler

14 {15 public voidHandle(OrderAddedEvent eventData)16 {17

18 Console.WriteLine("\r\n");19 Console.WriteLine("订单的数据是:");20 Console.WriteLine("订单号:" +eventData.Order.OrderId);21 Console.WriteLine("订单金额:" +eventData.Order.OrderAmount);22 Console.WriteLine("下单时间:" +eventData.Order.OrderDateTime);23

24 }25 }26 }

注:实现了IEventHandler接口,就是订阅了OrderAddedEvent事件

订单类

1 public classOrderEntity2 {3

4 ///

5 ///订单编号6 ///

7 public string OrderId { get; set; }8

9

10 ///

11 ///下单日期12 ///

13 public DateTime OrderDateTime { get; set; }14

15

16 ///

17 ///订单金额18 ///

19 public decimal OrderAmount { get; set; }20

21 }

发布事件

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Linq;4 usingSystem.Text;5

6

7 namespaceFramework.EventBus8 {9 classProgram10 {11 static void Main(string[] args)12 {13 EventBus bus =EventBus.Instance();14

15 OrderEntity order = new OrderEntity() { OrderId = "20151017001", OrderDateTime = DateTime.Now, OrderAmount = 500};16 bus.Publish(new OrderAddedEvent() { EventTime = DateTime.Now, Order = order }); //发布OrderAddedEvent事件,

17

19 Console.Read();20 }21

22 }23 }

运行结果

a3c804514744878bd3e0d1823cb2700b.png

改进

(1)实现基于msmq的事件总线,使得系统能够进行分布式的事件订阅和发布。

下载

参考资料

aspnetboilerplate

https://github.com/aspnetboilerplate/aspnetboilerplate

分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架

http://www.cxyclub.cn/n/53667/

Guava - EventBus(事件总线)

http://greengerong.com/blog/2014/11/27/guava-eventbus/

DDD~领域事件与事件总线

http://www.cnblogs.com/lori/p/3476703.html

事件总线 EventBus的设计

http://www.cnblogs.com/MartinChen999/archive/2011/12/21/2294034.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个简单的 Java 实现 DDD 的代码示例: 首先,我们需要定义一个领域对象(Domain Object),比如一个订单对象: ```java public class Order { private String orderId; private String customerId; private List<OrderItem> orderItems; private OrderStatus status; public Order(String orderId, String customerId, List<OrderItem> orderItems) { this.orderId = orderId; this.customerId = customerId; this.orderItems = orderItems; this.status = OrderStatus.NEW; } public void cancel() { this.status = OrderStatus.CANCELLED; } public void complete() { this.status = OrderStatus.COMPLETED; } // getters and setters } public enum OrderStatus { NEW, COMPLETED, CANCELLED } public class OrderItem { private String productId; private int quantity; public OrderItem(String productId, int quantity) { this.productId = productId; this.quantity = quantity; } // getters and setters } ``` 然后,我们需要定义一个领域服务(Domain Service),比如一个订单服务: ```java public class OrderService { private OrderRepository orderRepository; public OrderService(OrderRepository orderRepository) { this.orderRepository = orderRepository; } public void createOrder(String customerId, List<OrderItem> orderItems) { String orderId = UUID.randomUUID().toString(); Order order = new Order(orderId, customerId, orderItems); orderRepository.save(order); } public void cancelOrder(String orderId) { Order order = orderRepository.findById(orderId); order.cancel(); orderRepository.save(order); } public void completeOrder(String orderId) { Order order = orderRepository.findById(orderId); order.complete(); orderRepository.save(order); } } ``` 最后,我们需要定义一个仓储接口(Repository Interface),比如一个订单仓储: ```java public interface OrderRepository { Order findById(String orderId); void save(Order order); void delete(Order order); } ``` 以上就是一个简单的 DDD 实现Java 代码示例。在这个示例中,我们将领域对象和领域服务分离开来,通过仓储接口将领域对象持久化到数据库中,实现了领域模型的独立性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值