中介者模式其实理解起来还是蛮简单的,但是我看代码还是想了很久才逐渐弄明白。
中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
中介者模式由四个部分组成
- 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
- 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
- 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
- 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
网络上很多拿群聊天来举例,也挺贴近的,但我感觉更加贴近的是群发短信功能。
需求: 现在假设有这么个需求,有些人想要给别人发送短信,但挨个发又觉得麻烦,于是就想编辑一条短信,群发给所有联系人,那么这个“群发功能”就在这个需求中扮演了中介者的角色
概念不好理解,就拿代码来举例,按照中介者模式的四个组成部分来创建类文件
1.抽象中介者(Mediator)角色:AbsMediator
import java.util.ArrayList;
import java.util.List;
//抽象中介类:相当于群发功能抽象类
public abstract class AbsMediator {
//群发功能存储要发送的联系人列表
// 因为发送消息的人也可以通过这个中介接收消息,所以联系人列表也包括发送消息的人
protected List<AbsPeople> peopleList = new ArrayList<>();
//给群发功能添加要发送的联系人
public void addPeople(AbsPeople people){
if(!peopleList.contains(people)){//避免重复添加
//这两步操作至关重要,缺一不可
peopleList.add(people);//将这个联系人添加到群发功能联系人列表
people.setMediator(this);//把这个联系人和这个群发功能绑定在一起
}
}
//群发功能转发短信的抽象方法
public abstract void relay(AbsPeople talkContent);
}
2.具体中介者(ConcreteMediator)角色:Mediator
//具体中介类:群发功能的具体实现
public class Mediator extends AbsMediator {
@Override
public void relay(AbsPeople people) {
for (AbsPeople p : peopleList) {
//从联系人列表中查找,只要不是发消息的人,就要让其收到消息
if(!p.equals(people))
p.receive();//所有联系人收到消息后也会通过这个群发功能中介发送自己的回复信息
}
}
}
3.抽象同事类(Colleague)角色:AbsPeople
//抽象联系人
public abstract class AbsPeople {
protected AbsMediator mediator;//每个人都要关联这个群发功能
public void setMediator(AbsMediator mediator){//让联系人绑定群发功能
this.mediator = mediator;
}
//联系人可以发送消息也可以接收消息
public abstract void send();//发出一句话
public abstract void receive();//接收一句话
}
4.具体同事类(Concrete Colleague)角色:People
//具体联系人
public class People extends AbsPeople {
String name;
public People(String name) {
this.name = name;
}
@Override
public void send() {
System.out.println(name+":我发了一句话,收到请回复 “已收到”");
//让中介者转发要发出去的话
mediator.relay(this);
}
@Override
public void receive() {
System.out.println(name+":已收到");
}
}
5.编写一个客户端测试类来测试下结果:
public class Client {
public static void main(String[] args) {
AbsMediator mediator = new Mediator();//实例化中介类
AbsPeople p1,p2,p3,p4;//初始化多个联系人
p1 = new People("张三");
p2 = new People("李四");
p3 = new People("王五");
p4 = new People("赵六");
//将这些联系人添加到中介角色 - 群发功能中
mediator.addPeople(p1);
mediator.addPeople(p2);
mediator.addPeople(p3);
mediator.addPeople(p4);
//让绑定好的用户发送一句话,然后交给中介转发给其他人来测试回复效果
p1.send();
System.out.println("----------------");
p2.send();
System.out.println("----------------");
p3.send();
System.out.println("----------------");
p4.send();
}
}
输出结果如下图:
这样就实现了中介转发的功能,代码并不复杂,多看几遍就能理解了。