在现实生活中,经常会出现好多对象之间存在复杂的交互关系,这种交互关系经常是“网状结构”,它要求每一个对象都必须知道它须要交互的对象。例如,每一个人必须记住他(她)全部朋友的电话;并且,朋友中若是有人的电话修改了,他(她)必须告诉其余全部的朋友修改,这叫做“牵一发而动全身”,很是复杂。
若是把这种“网状结构”改成“星形结构”的话,将大大下降它们之间的“耦合性”,这时只要找一个“中介者”就能够了。如前面所说的“每一个人必须记住全部朋友电话”的问题,只要在网上创建一个每一个朋友均可以访问的“通讯录”就解决了。这样的例子还有不少,例如,你刚刚参力口工做想租房,能够找“房屋中介”;或者,本身刚刚到一个陌生城市找工做,能够找“人才交流中心”帮忙。
在软件的开发过程当中,这样的例子也不少,例如,在 MVC 框架中,控制器(C)就是模型(M)和视图(V)的中介者;还有你们经常使用的 QQ 聊天程序的“中介者”是 QQ 服务器。全部这些,均可以采用“中介者模式”来实现,它将大大下降对象之间的耦合性,提升系统的灵活性。服务器
通常在如下状况下能够考虑使用中介者模式:框架
中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且能够独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
中介者模式是一种对象行为型模式,其主要优势以下。spa
其主要缺点是:当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以致于系统难以维护。code
在实际开发中,常常会简化中介者模式,来是开发变得简单,好比有以下的简化。对象
通过这样的简化、变形的状况称为广义中介者。blog
中介者模式就是经过一个中介者,来让多个交错纵横的引用的类相互解耦,经过访问中介者类的方法就能够访问其余类的方法,每一个类之间是相互平等的。好比下面的代码,咱们有一个学生类,一个教师类,咱们在控制器中有两个Action来处理这两个类的新增,那咱们的实现应该是以下的:继承
public class Student{//属性...} public class Teacher{//属性...}
服务类接口
public class StudentService { public void Add(Student entity){//添加方法} } public class TeacherService { public void Add(Teacher entity){//添加方法} }
控制器的实现,能够看到有多个服务类被实例化。开发
public class AddController : Controller { StudentService studentService = new StudentService(); TeacherService teacherService = new TeacherService(); public IActionResult Student(Student entity) { studentService.Add(entity); return Content("添加成功"); } public IActionResult Teacher(Teacher entity) { teacherService.Add(entity); return Content("添加成功"); } }
若是咱们用了中介者模式,那就能够免去这些服务类的实例化,直接使用中介者类执行对应的添加方法就好了,下面就进行简单的实现。get
下面只是经过简单的例子来体现中介者模式的思想,不用过于纠结是否合理,咱们能够在实际项目中按本身的需求来实现,就想上面描述的广义的中介者模式。
学生类和教师类以及对应的服务类
public class Base{} public class Student : Base{//属性...} public class Teacher : Base{//属性...} public class StudentService { public string Add(Student entity){return "已添加学生";} } public class TeacherService { public string Add(Teacher entity){return "已添加教师";} }
中介者类
public interface IMediator{string Add(Base entity);} public class Mediator : IMediator { private StudentService studentService = new StudentService(); private TeacherService teacherService = new TeacherService(); public string Add(Base entity) { if(entity is Student) return studentService.Add((Student)entity); else if (entity is Teacher) return teacherService.Add((Teacher)entity); return "添加失败"; } }
控制器中使用中介者类
public class AddController : Controller { private IMediator iMediator = new Mediator(); public IActionResult Student(Student entity) { return Content(iMediator.Add(entity)); } public IActionResult Teacher(Teacher entity) { return Content(iMediator.Add(entity)); } }
访问学生新增接口就会出现以下结果:
经过 .NET CORE 自带的 IoC 注入
引用 MediatR nuget:install-package MediatR
引用IOC扩展 nuget:installpackage MediatR.Extensions.Microsoft.DependencyInjection //扩展包
在Startup类中的ConfigureServices方法中注册MediatR服务,下面这句话能够扫描继承IRequestHandler接口的实现对象并添加到IOC的容器中
services.AddMediatR(typeof(Startup).GetTypeInfo().Assembly);
为咱们的学生类和教师类继承IRequest接口,表示该对象是处理器的一个对象。
public class Student : IRequest<string>{//属性...} public class Teacher : IRequest<string>{//属性...}
为咱们的服务类添加IRequestHandler接口建立处理器对象。
public class StudentService : IRequestHandler<Student,string> { public Task<string> Handle(Student entity, CancellationToken cancellationToken) { return Task.FromResult("已添加学生"); } } public class TeacherService : IRequestHandler<Teacher, string> { public Task<string> Handle(Teacher entity, CancellationToken cancellationToken) { return Task.FromResult("已添加教师"); } }
在控制器中使用,经过调用中介者的Send方法,自动匹配对应使用该处理器对象的处理器方法。
public class AddController : Controller { private readonly IMediator _mediator; public AddController(IMediator mediator) { _mediator = mediator; } public IActionResult Student(Student entity) { return Content(_mediator.Send(entity).Result); } public IActionResult Teacher(Teacher entity) { return Content(_mediator.Send(entity).Result); } }
这样咱们的改造就完成了。继承IRequest接口有一个泛型表示处理器返回参数类型,与IRequestHandler接口的第二个参数和IRequestHandler接口定义的方法Handle方法的返回值对应,能够不定义表示返回void。IRequestHandler接口的第一个参数必须为继承IRequest接口的类。