概述
基本介绍
1、中介者模式(Mediator Pattern):用一个中介对象来封装一系列的对象交互。中介者使各个对象不需要显示的相互引用,从而使其耦合度降低,而且可以独立的改变它们直接的交互,使代码易于维护。属于行为型模式。
2、对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。
3、比如MVC模式,C(controller控制器)是M(model模型)个V(view视图)的中介者,在前后端交互的时候,起到了中介的作用。
中介者模式原理类图
中介者模式角色与职责介绍
Mediator:抽象中介者,定义了同事对象到中介者对像的接口。
ConcreteMediator:具体的中介者对象,实现抽象方法,需要知道所有的具体的同事类。以集合的形式去管理具体同事类,并接收某个同事对象的消息,完成相应的任务。
Colleague:抽象同事类,管理子系统的父类
ConcreteColleague:具体同事类,每个同事类只知道自己的行为,而不了解其它同事类的行为,但是它们都会依赖中介者对象。
中介者模式应用案例
需求:租客-房屋中介-房东的信息传递的案例
应用案例类图分析
中介者模式-房屋出租流程简介
1、创建ConcreteMediator对象。
2、创建各个具体同事类对象,比如:租客、房东等等。
3、在创建具体同事类对象的时候,直接通过构造器加入到colleagues容器中。
4、同事类对象可以调用sendMsg方法,最终会调用ConcreteMediator中的getMsg方法。
5、getMsg方法会根据接收到的同事对象发出的消息来协调调用其它的同事类对象,完成相应任务。
6、ConcreteMediator对象中的getMsg需要处理很多业务逻辑,是核心方法,完成相应调用。
代码实现
package com.example.pattern.mediator.improve;
import lombok.Getter;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 中介者模式
*/
@Getter
public abstract class Person { // 抽象同事类
private Mediator mediator; // 聚合一个抽象中介者
private String name; // 用户信息
public Person(Mediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public abstract void sendMsg(String msg); // 向中介者 发送消息
public abstract void getMsg(String msg); // 从中介者 获取消息
public abstract void register(); //向中介注册
}
class Renter extends Person { // 具体同事类 租房者
public Renter(Mediator mediator, String name) {
super(mediator, name);
this.register();
}
@Override
public void sendMsg(String msg) {
this.getMediator().operation(this, msg);
}
@Override
public void getMsg(String msg) {
System.out.println("租房者[" + this.getName() + "]\t接收到到中介发送的信息:" + msg);
}
@Override
public void register() {
this.getMediator().register(this);
}
}
class Landlord extends Person { // 具体同事类 房东用户
public Landlord(Mediator mediator, String name) {
super(mediator, name);
this.register();
}
@Override
public void sendMsg(String msg) {
this.getMediator().operation(this, msg);
}
@Override
public void getMsg(String msg) {
System.out.println("房东[" + this.getName() + "]收到中介发来的消息:" + msg);
}
@Override
public void register() {
this.getMediator().register(this);
}
}
@Getter
abstract class Mediator { // 抽象中介者
// 注册进入中介者的角色对象
private List<Person> personList;
public void register(Person person) { // 用户向中介者注册
if (CollectionUtils.isEmpty(personList)) {
personList = new ArrayList<>();
}
personList.add(person);
}
// 声明一个抽象方法 目的是消息的中转与发送
public abstract void operation(Person person, String msg);
}
class ConcreteMediator extends Mediator {// 具体中介者
@Override
public void operation(Person person, String msg) {
if (person instanceof Renter) { // 用户是租房者 向注册的房东们发送信息
List<Person> landlordList = this.getPersonList().stream()
.filter(item -> item instanceof Landlord).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(landlordList)) {
landlordList.forEach(item -> item.getMsg(msg));
}
} else if (person instanceof Landlord) { // 用户是房东 向注册的租房者用户发送消息
List<Person> renterList = this.getPersonList().stream()
.filter(item -> item instanceof Renter).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(renterList)) {
renterList.forEach(item -> item.getMsg(msg));
}
}
}
}
class Client{
public static void main(String[] args) {
// 中介者
Mediator mediator = new ConcreteMediator();
// 具体同事类 房东
Landlord landlordA = new Landlord(mediator, "房东A");
Landlord landlordB = new Landlord(mediator, "房东B");
// 具体同事类 租客
Renter renterA = new Renter(mediator, "租客A");
Renter renterB = new Renter(mediator, "租客B");
// 租客 发送消息
renterA.sendMsg("需要租房");
System.out.println("-------------");
landlordA.sendMsg("这里有");
System.out.println("-------------");
renterB.sendMsg("多少money");
System.out.println("-------------");
landlordB.sendMsg("面谈");
}
}
上面的代码只是最简单的实现租房者与房东直接的多对多沟通,若是具体同时类直接的关系更加复杂,则具体中介者的逻辑更加复杂,比如:
我们来实现一个简化版的数据同步方案,有三种数据库 Mysql、Redis、Elasticsearch,其中的 Mysql 作为主数据库,当增加一条数据时需要同步到另外两个数据库中;Redis 作为缓存数据库,当增加一条数据时不需要同步到另外另个数据库;而 Elasticsearch 作为大数据查询数据库,有一个统计功能,当增加一条数据时只需要同步到 Mysql。
请参考博客 设计模式 | 中介者模式及典型应用。
总结
中介者模式将一个复杂的网状系统结构变成一个以中介者为中心的星形结构,具体同事类之间的复杂调用关系,被中介者对象的以对多关系取代。
优点
1、中介者模式简化了对象之间的交互,它用中介者和具体同事类的一对多关系代替了原来的多对多关系,一对多关系较为容易扩展和维护。
2、中介者模式将具体同事类之间解耦。中介者有减少同事类之间的耦合,可以独立的改变和复用每一个同事类和中介者,增加新的中介者和同事类也比较方便,符合OCP原则。
3、可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
缺点
中介者模式在具体中介者类中包含了大量同事类之间的交互细节,可能会导致具体中介者类变得非常复杂,系统难以维护。
具体同事类之间的交互复杂性集中到了中介者类中,结果中介者成了最复杂的类
以后自己回看设计模式的时候把这个再好好想想。中介者模式和访问者模式比较复杂,也没有想出来实际运用的案例,先将学习的内部记录下来,需要好好思考。