中介者模式(Mediator Design Pattern),是通过一个中介对象,来封装多个对象之间的交互,将原本直接沟通的A和B,变为A<–>中介者<–>B。
比如我们现在用的微信聊天,张三的微信账号,有30个好友,他的每个好友也各自有30各好友,并且好友之间也有重叠。如果微信的设计是点对点发送消息,点对点也就是张三和他的好友A发消息,是直接从张三手机将消息发给A的手机,那么张三如果同时和他的30个好友聊天,并且他的30个好友也同时和各自的30个好友聊天,这将组成一个庞大的网,关系错综复杂。
有没有一种方法,让这种复杂的场景变得简单呢?
那就是我们本节的主角中介者模式了。
中介者模式就是作为消息的中转者,不管是谁,发消息,都是发到中介者,由中介者转发,这样就从一种网状关系,变成了星状结构,中介者在模式中就是星状结构的中心。
我们先来演示一个简单的例子,三个用户A、B、C一起聊天,A、B、C都是讲消息发送给中介者,通过中介者将消息广播出来。
1、新建中介者类
package com.itzhimei.study.design.mediator;
/**
* www.itzhimei.com
* 中介者
*/
public class Mediator {
public static void showMessage(User user,String message) {
System.out.println("用户"+user.getName()+":"+message);
}
}
2、新建用户类
package com.itzhimei.study.design.mediator;
/**
* www.itzhimei.com
* 用户
*/
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sendMessage(String message) {
Mediator.showMessage(this, message);
}
}
3、测试
package com.itzhimei.study.design.mediator;
public class Client {
public static void main(String[] args) {
User a = new User("A");
User b = new User("B");
User c = new User("C");
a.sendMessage("大家好,我是A");
}
}
输出结果:
用户:A:大家好,我是A
通过中介者,三个用户A、B、C之间就实现了解耦。
类关系图:
上面的demo有点简单,中介者发消息的动作不那么形象,我们再对上面的代码进行一点改造。
1、定义中介者接口
package com.itzhimei.study.design.mediator.mda;
/**
* www.itzhimei.com
* 中介者接口
*/
public interface IMediator {
/**
* 注册用户
*/
void regist(IUser user);
/**
* 中转消息给其他用户
* @param user
*/
void notifyAllMessage(IUser user);
}
2、定义中介者实体
package com.itzhimei.study.design.mediator.mda;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* www.itzhimei.com
* 中介者:定义职责 1、注册持有用户 2、转发消息
*/
public class Mediator implements IMediator {
private List<IUser> userList = new ArrayList<>();
@Override
public void regist(IUser user) {
if(user != null && !userList.contains(user)) {
userList.add(user);
}
}
@Override
public void notifyAllMessage(IUser user) {
if(!userList.isEmpty()) {
Iterator<IUser> iterable = userList.iterator();
while(iterable.hasNext()) {
IUser u = iterable.next();
if(u != null && !u.equals(user)) {
u.receiveMessage(user.getMessage());
}
}
}
}
}
中介者中有两个方法,1、注册持有用户 2、转发消息
3、定义用户接口
package com.itzhimei.study.design.mediator.mda;
public interface IUser {
void receiveMessage(String message);
void sendMessage(String message);
String getMessage();
}
4、定义抽象用户,实现用户通用行为,定义用户通用属性
package com.itzhimei.study.design.mediator.mda;
/**
* www.itzhimei.com
* 用户抽象类:持有中介者
*/
public abstract class AbstractUser implements IUser {
private IMediator mediator;
private String name;
private String message;
public AbstractUser(IMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public void sendMessage(String message) {
this.message = message;
mediator.notifyAllMessage(this);
}
public IMediator getMediator() {
return mediator;
}
public void setMediator(IMediator mediator) {
this.mediator = mediator;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
在这其中,就持有了中介者,用于用户注册到中介者,并用中介者发送信息。
5、测试
package com.itzhimei.study.design.mediator.mda;
/**
* www.itzhimei.com
* 测试
*/
public class Client {
public static void main(String[] args) {
IMediator m = new Mediator();
IUser a = new User(m,"A");
IUser b = new User(m,"B");
IUser c = new User(m,"C");
//发送消息
a.sendMessage("hello world");
}
}
测试输出:
用户B收到:hello world
用户C收到:hello world
用户A发送的消息,B和C都收到了,最终达到了用户之间的解耦。
这就是中介者的作用。
类关系图:
中介者模式中包含的角色:
抽象中介者:定义中介者的职责,之所以有抽象中介者,其实就是遵循设计模式的依赖倒置原则。
具体中介者:实现中介者的具体实现类,职责包括注册用户、转发消息。
抽象用户:定义用户行为和属性。
具体用户:实际用户,发送和接收消息。
总结:
中介者模式是使用一个中间角色来处理多个角色之间的关系,比如通信关系,通过中介自身来解耦多个角色,让系统角色的整体关系更加简单。