定义
定义一个 封装一组对象如何交互的 对象。主要解决多个对象和类之间的通信复杂度,主要通过一个中介类接受所有消息,然后再进行转发。
通过使封装交互对象的明确的相互引用来促进松散耦合,并允许独立地改变它们的交互。这样可以降低多个对象和类之间的通信复杂度,由原来的网状接口转变为星型结构。
类型
行为型
适用场景
- 系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解
- 交互的公共行为,如果需要改变行为则可以增加新的中介者类(比如聊天室)
优点
- 将一对多转化为一对一,降低程序的复杂度(比如QQ群,如果没有群,就需要对其他人全部发一遍消息,现在只需要在群中发消息即可)
- 类之间解耦
缺点
同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
UML类图
- Colleague:同事接口,主要负责约束同事对象的类型,并实现一些具体同事类之间的公共功能,比如:每个具体同事类都应该知道中介者对象,也就是具体同事类都会持有中介者对象,就可以定义到这个类里面。
- ConcreteColleague:具体的同事类,实现自己的业务,在需要与其它同事通讯的时候,就与持有的中介者通信,中介者会负责与其它的同事交互。
- Mediator:中介者接口。在里面定义各个同事之间交互需要的方法,可以是公共的通讯方法,比如changed方法,大家都用,也可以是小范围的交互方法。
- ConcreteMediator:具体中介者实现对象。它需要了解并维护各个同事对象,并负责具体的协调各同事对象的交互关系。
代码实例
以聊天室为例,下面是UML图
- User(Colleague)
public abstract class User {
protect Mediator mediator;
String name;
public User(String name, Mediator mediator){
this.name = name;
this.mediator = mediator;
}
abstract void sendToAll(String msg);//给所有人发消息
abstract void senToPerson(String msg, String name);//给某个人发送消息
abstract void accept(String msg);//接受消息
abstract void join();//加入聊天室
abstract void leave();//离开聊天室
}
- NormalUser(ConcreteColleague)
public class NormalUser extends User {
public NormalUser(String name, Mediator mediator) {
super(name, mediator);
}
@Override
void sendToAll(String msg) {
mediator.sendToAll(msg);
}
@Override
void senToPerson(String msg, String name) {
mediator.senToPerson(msg, name);
}
@Override
void accept(String msg) {
System.out.println(this.name + "收到消息:" + msg );
}
@Override
void join() {
mediator.join(this);
}
@Override
void leave() {
mediator.leave(this);
}
}
- Mediator
public abstract class Mediator{
List<User> list = new ArrayList<>();//所有在聊天室里的人
abstract void sendToAll(String msg);//群发
abstract void senToPerson(String msg, String name);//给某个人发送消息
abstract void join(User user);//用户加入聊天室
abstract void leave(User user);//用户离开聊天室
}
- ChatPlatform(ConcreteMediator)
public class ChatPlatform extends Mediator {
@Override
void sendToAll(String msg) {
for (User u : list){
u.accept(msg);
}
}
@Override
void senToPerson(String msg, String name) {
for (User u : list){
if (u.name.equals(name))
u.accept(msg);
}
}
@Override
void join(User user) {
list.add(user);
}
@Override
void leave(User user) {
list.remove(user);
}
}