领域事件
我们知道领域模型的变化会产生领域事件。例如,用户在完成注册后,系统会发出一封带有确认信息的邮件到用户的邮箱;用户关注的好友发送动态后他会收到相应的通知等等。在业务比较简单或者不用考虑性能的情况下,我们可以直接把对领域事件的处理嵌入到领域服务中。考虑这样一个场景:用户回复了某条评论,那么被回复的那个用户(也就是那条评论的所有者)需要收到一个PUSH消息。
如果直接把发送PUSH的动作嵌入到了回复的逻辑中。这样做有以下两个问题:
- 回复动作处理了它不关心的逻辑。发送PUSH不是回复的强关联逻辑,也就是说即使push发送不成功也应该让回复动作成功。上面的代码将回复和发送PUSH耦合在了一起。
- 如果出现了多个对回复动作感兴趣的业务方,那么上面的代码将不可维护。比如,我们有一个回复的计数器,它要统计回复的总量。如果把增加计数器的动作写在回复中,那么将不可维护,因为每次出现新的业务方都要修改回复逻辑。这显然返回了
开闭原则
解决上诉问题的方法很简单,就是使用领域事件
。领域事件
很好理解,说白了就是与领域相关的事件。事件的产生往往伴随着相应的动作,例如上面所提到的回复动作。有了领域事件,每个领域本身就只需要关系其自己的业务逻辑,并在处理完自身逻辑的同时抛出相应的领域事件。对这些领域事件感兴趣的业务方可以订阅
该事件,然后进行后续的处理。这与观察者
模式和发布订阅
模式是十分相像的。我更倾向于发布订阅
这个词,它更好的表达了发布者和订阅者的一种解耦。
通过领域事件达到松耦合的效果。
观察者模式
pring ApplicationContext 事件机制
ApplicationContext 中事件处理是由 ApplicationEvent 类和 ApplicationListener 接口来提供的。如果一个Bean实现了 ApplicationListener 接口,并且已经发布到容器中去,每次 ApplicationContext 发布一个 ApplicationEvent 事件,这个Bean就会接到通知。
使用ApplicationContext发布一个ApplicationEvent:
遍历所有的ApplicationListener,调用listener的onApplicationEvent方法
扩展:
观察者模式跟发布订阅模式的区别:
1、在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
2、在发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。
3、观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。