概要
中介者模式
什么是中介者模式
中介者模式即对象通过中介者交互而非直接进行。
中介者模式让原本类之间的依赖转移到为了中介者与类间,由此在很大程度上降低程序的耦合度,并大大简化类之间的通信。
中介者类似消息的处理中心,对象向中介者发送请求,中介者分发请求至对应目标。获得目标响应后返回至发起者。
为什么要使用中介者模式
1.程序随功能增多产生复杂的依赖关系,某一方法可能分别依赖不同层级的对象
2.类间的通信、调用流程由于多对多的关系变得繁琐
3.由于类间的相互引用而产生高耦合的代码
中介者模式如何解决问题
以WebApi工程为例,最上层的controller只依赖于中介者对象,中介者对象依赖于业务逻辑。
1.根据中介者的位置进行分割,此时中介者作为controller和业务逻辑之间的分隔起到解耦的作用。上层的controller与下层的业务逻辑始终只与中介者交互,两部分即消息的发送和接收者可以独立的修改,controller的替换或者更新的工作量也就大大减少。
2.在我们对所有的逻辑都尽可能地进行分割的前提下,通过于中介者交互获得某一逻辑片段的响应,组合后完成复杂逻辑。
原本的复杂逻辑可能依赖于多个下层方法,分隔后复杂逻辑只依赖于中介者。
原本依赖的多个下层方法现在分布在各个逻辑片段中,由此,下层方法的改动只对这些逻辑片段产生影响。
3.以复杂逻辑为例,中介消息的接收者只表明调用各个逻辑的顺序以及组合方式。逻辑片段及其依赖的下层方法的修改只要保证自身的返回内容正确,符合请求目的,就不会对其他的所依赖的对象产生影响
中介者模式存在的问题
有的朋友可能说了,我只要写一个巨大的类,把所有的业务逻辑的方法都放进去,让所有的controller都依赖于这个类,那我是不是也实现了中介者模式?
从结构上来说,这个类也是起到了中介者的角色。但是随着业务增加,中介者对象变得臃肿庞大。
其次这个巨大的类相当于对所有的下层方法产生了依赖,每次使用这个类时,都需要将所有的依赖注入,与依赖注入的目的相违背。
而MediatR在一定程度上解决了这个问题。MediatR提供了简洁且功能丰富的中介者对象
并将依赖向外部分散,依赖注入到细致的下层逻辑中
MediatR
.NET中的中介者模式实现,一种进程内消息传递框架,提供了中介者对象
MediatR支持以同步或异步的形式进行请求/响应,支持消息的单播/多播
WebApp中应用MediatR
MediatR在WebApi中的位置处于Application与Presentation/Controller之间,请求进入后发送通过MediatR消息,消息处理方法中调用Application
由此,MediatR作为Presentation/Controller和Application的中间连接件,前者只对MediatR产生依赖,而MediatR只对后者产生依赖
把MediatR inject 到 presentation和把service inject到presentation有什么区别和各自的利弊?
首先就是两个依赖关系不一样 理想状态下是presentation只对mediator中介者产生依赖 如果是service直接注入的话 通常情况下不可能只注入一个 presentation就会产生多个引用 增加两者之间的耦合
MediatR把presentation和service分隔开来 这样两个部分的修改变更就更简单
优势是MediatR能分散所有的依赖 降低耦合
弊端是中介者成了程序不能分割的一部分 所以他必须要可靠高效
直接调用与通过MediatR调用比较
功能 |
通过MediaR调用 |
调用方法的前后进行额外处理 |
通过IPipelineBehavior实现类似中间件的功能,通过IRequestPreProcess,IRequestpostProcess来实现为某一方法调用前后附上额外运行的代码 |
调用方法触发运行一个或多个代码段 |
通过INotification实现消息的单播/多播 |
捕捉异常 |
通过IRequestExceptionHandler,IRequestExceptionAction处理执行方法中产生的异常,运行额外代码 |
Notification消息的发布策略
通过重写MediatR.PublishCore方法来实现自定义的发布策略
默认发布策略是遍历所有消息的handlers, 逐一执行