浅析Mediator

本文详细介绍了如何运用Mediator模式轻松实现命令查询职责分离(CQRS)。首先,通过自定义命令类和IRequestHandler实现命令处理;接着,利用领域事件让处理更加优雅,通过CustomEvent和INotificationHandler实现事件的发布与订阅。最后,提供了源码下载供读者参考。

一、轻松实现命令查询职责分离模式(CQRS)

1.自定义命令类

代码如下(示例):

class CustomCommand : IRequest<long>
    {
        public string Name { get; set; }
    }

2.自定义实现IRequestHandler的类

CustomCommandHandler 通过泛型参数来关联CustomCommand

代码如下(示例):

class CustomCommandHandler : IRequestHandler<CustomCommand, long>
    {
        public Task<long> Handle(CustomCommand request, CancellationToken cancellationToken)
        {
            Console.WriteLine($"CustomCommand执行命令:{request.Name}");
            return Task.FromResult(100L);
        }
    }

3.通过Send来调用CustomCommand

代码如下(示例):

 var services = new ServiceCollection();
            var assembly = typeof(Program).Assembly;
            services.AddMediatR(assembly);
            var serviceProvider = services.BuildServiceProvider();
            var mediator = serviceProvider.GetService<IMediator>();
            mediator.Send(new CustomCommand() {Name="testName" });

二、让领域事件处理更加优雅

1.自定义CustomEvent类继承INotification

代码如下(示例):

class CustomEvent: INotification
    {
        public string Name { get; set; }
    }

2.自定义实现INotificationHandler的类

代码如下(示例):
CusotmEventHandler1 :

class CusotmEventHandler1 : INotificationHandler<CustomEvent>
    {
        public Task Handle(CustomEvent notification, CancellationToken cancellationToken)
        {
            Console.WriteLine($"CusotmEventHandler1 do sth:{notification.Name}");
            return Task.CompletedTask;
        }
    }

CusotmEventHandler2 :

 class CusotmEventHandler2 : INotificationHandler<CustomEvent>
    {
        public Task Handle(CustomEvent notification, CancellationToken cancellationToken)
        {
            Console.WriteLine($"CusotmEventHandler2 do sth:{notification.Name}");
            return Task.CompletedTask;
        }
    }

3.通过Publish来调用实现了INotificationHandler的类

代码如下(示例):

 var services = new ServiceCollection();
            var assembly = typeof(Program).Assembly;
            services.AddMediatR(assembly);
            var serviceProvider = services.BuildServiceProvider();
            var mediator = serviceProvider.GetService<IMediator>();
            await  mediator.Publish(new CustomEvent { Name = "testEventPublish" });

三、源码下载

下载

总结

Send是1:1,只能发送一个命令对象,后面的后覆盖前面的。
Publish是1:*,只要实现了INotificationHandler接口的类都能接受到消息。

### Mediator 设计模式的概念 Mediator 是一种行为型设计模式,其主要目的是通过引入一个中介对象来封装一组对象之间的交互关系。这种方式可以减少类间的耦合度,使得各个对象无需显式地相互引用即可实现协作[^1]。 在实际开发过程中,当多个组件之间存在复杂的依赖关系时,这些依赖可能会导致系统的可维护性和扩展性变差。而 Mediator 模式则可以通过集中管理这些依赖关系,使各组件仅需与中介者通信,从而降低复杂性并提高灵活性[^2]。 ### Mediator 的结构和角色定义 #### 1. **Mediator** 这是抽象中介者的接口或基类,它声明了用于同事(Colleague)对象与其进行沟通的方法。具体实现由子类完成。 #### 2. **ConcreteMediator** 该类实现了 `Mediator` 接口的具体逻辑,并协调各个同事对象的行为。它保存着对所有同事实例的引用,并负责在其间传递消息。 #### 3. **Colleague (同事类)** 代表参与合作的对象集合中的每一个成员。它们只知道自己的功能需求以及如何向中介发送请求或者接收来自中介的通知;除此之外并不关心其他任何细节。 以下是基于 Python 实现的一个简单例子: ```python from abc import ABC, abstractmethod class IMediator(ABC): @abstractmethod def send(self, message, colleague): pass class ConcreteMediator(IMediator): def __init__(self): self.colleagueA = None self.colleagueB = None def set_colleagues(self, colA, colB): self.colleagueA = colA self.colleagueB = colB def send(self, message, colleague): if colleague == self.colleagueA: self.colleagueB.notify(message) elif colleague == self.colleagueB: self.colleagueA.notify(message) class Colleague(ABC): def __init__(self, mediator): self.mediator = mediator @abstractmethod def send_message(self, message): pass @abstractmethod def notify(self, message): pass class ColleagueA(Colleague): def send_message(self, message): self.mediator.send(message, self) def notify(self, message): print(f"Colleague A received: {message}") class ColleagueB(Colleague): def send_message(self, message): self.mediator.send(message, self) def notify(self, message): print(f"Colleague B received: {message}") if __name__ == "__main__": med = ConcreteMediator() a = ColleagueA(med) b = ColleagueB(med) med.set_colleagues(a, b) a.send_message("Hello from A") # 输出:Colleague B received: Hello from A b.send_message("Hi back to you!") # 输出:Colleague A received: Hi back to you! ``` 上述代码展示了两个同事类 (`ColleagueA`, `ColleagueB`) 如何借助于具体的中介者 (`ConcreteMediator`) 来互相交流而不直接彼此调用方法[^4]。 ### 使用场景分析 - 当应用程序中有许多不同类型的对象需要相互通信时; - 如果发现某些类因为与其他太多类有联系而导致难以理解、修改或测试的时候; - 需要创建松散耦合的设计以便更容易管理和重用单个部件的情况下适用此模式[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值