设计模式 - 中介者模式
中介者模式:用中介对象来封装一系列对象的交互,使各对象不需要显式地相互依赖,松散耦合,使类的改动局限于类本身和中介类
核心:星型拓扑,由中介者作为通信中枢(一中介者:多同事类,同事类之间解除依赖)
角色:
- 具体中介类Mediator:作为所有同事类的依赖,作为通信中枢。
- 具体同事类Colleague:执行功能逻辑,以及与中介类进行交互(从而实现与其他同事的交互)。
PS:需根据业务场景决定,是否需要抽象出同事类的共性接口。
general
// 最基本的中介者模式,Mediator完成通信转发的职责
public class Mediator {
private ConcreteColleageA concreteColleageA = new ConcreteColleageA(this);
private ConcreteColleageB concreteColleageB = new ConcreteColleageB(this);
public void doMethodA() {
System.out.print("Mediator call -> ");
concreteColleageA.selfMethodA();
}
public void doMethodB() {
System.out.print("Mediator call -> ");
concreteColleageB.selfMethodB();
}
}
// 同事抽象,封装共性(当同事对象各有不同功能时,具体功能只能由子类自行实现,而无法作为共性封装)
public abstract class Colleage {
// 同事类需要持有中介者的引用,通过中介者实现与其他同事类的交互
protected Mediator mediator;
protected Colleage(Mediator mediator){
this.mediator = mediator;
}
}
public class ConcreteColleageA extends Colleage{
protected ConcreteColleageA(Mediator mediator) {
super(mediator);
}
// 自有方法,由类自己实现
public void selfMethodA(){
System.out.println("ColleageA - Do method A!");
}
// 依赖方法,需要调用其他类实现(在中介者模式中,通知中介类,由中介类去协调处理)
public void dependenceMethodB(){
System.out.print("ColleageA call method B-> ");
mediator.doMethodB();
}
}
// 功能不同的同事,由中介者实现消息转发 ---》 使同事类之间解耦(网状 -》 星状) --- 实例:服务治理
// 使同事类的改动范围限制在自身和中介类中, 弊端:中介类可能会很复杂。
public class Test {
public static void main(String[] args) {
Mediator mediator = new Mediator();
ConcreteColleageA concreteColleageA = new ConcreteColleageA(mediator);
ConcreteColleageB concreteColleageB = new ConcreteColleageB(mediator);
concreteColleageA.dependenceMethodB(); // ColleageA call method B-> Mediator call -> ColleageB - Do method B!
concreteColleageA.selfMethodA(); // ColleageA - Do method A!
concreteColleageB.dependenceMethodA(); // ColleageB call method A-> Mediator call -> ColleageA - Do method A!
concreteColleageB.selfMethodB(); // ColleageB - Do method B!
}
}
ChatRoom
// 一种较为特殊的中介者模式,此时,中介者行使一种平台的功能,所有用户均与平台进行操作。
public class ChatRoom {
List<Message> messages = new ArrayList<>();
public void receive(User user, String message){
messages.add(new Message(user.getUsername(), new Date(), message));
}
public void show(){
for(Message message : messages){
System.out.println(message.username + " " + CommonUtils.simpleFormatDate(message.date) + "\n" + message.message);
}
}
// 封装的消息对象,只有ChatRoom可以操作
private class Message {
private String username;
private Date date;
private String message;
public Message(String username, Date date, String message) {
this.username = username;
this.date = date;
this.message = message;
}
}
}
public class User {
private String username;
public User(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void chat(ChatRoom chatRoom, String message){
chatRoom.receive(this,message);
}
}
// 中介者作为平台,为所有同事对象提供平台的功能。(同事只需和中介者交互)
public class Test {
public static void main(String[] args) {
ChatRoom chatRoom = new ChatRoom();
User userA = new User("kiqi");
User userB = new User("xike");
userA.chat(chatRoom,"你啥时候放假?");
userB.chat(chatRoom,"不知道啊,下周四吧");
userA.chat(chatRoom,"这样吗,好早啊,我这都没下通知!!!");
userB.chat(chatRoom,"哦,这样子的老板,炒了吧,我养你!");
chatRoom.show();
}
}
简化服务治理
// 中介者,维护所有的服务列表,同时负责转发服务请求
public class Mediator {
// 服务管理者只能有一份,使用单例模式创建
private final static Mediator mediator = new Mediator();
private Mediator() {}
public static Mediator getInstance(){
return mediator;
}
// 维护所有的服务列表<serviceId, service实例>
private Map<String, AbstractService> serviceMap = new HashMap<>();
// 服务需要注册到Mediator中,才能被其他服务调用
public final void register(String serviceId, AbstractService service){
serviceMap.put(serviceId, service);
}
// 根据serviceId查找对应的服务对象,并将调用方法名和参数传递过去
public Object relay(String serviceId, String method, Object[] params){
System.out.println("Mediator.relay() - " + serviceId + "." + method + "()");
if (serviceMap.containsKey(serviceId)) {
AbstractService service = serviceMap.get(serviceId);
return service.receive(method, params);
}
return null;
}
}
// 抽象服务类,共性:均需注册到Mediator中,且,需要一个统一的接口作为请求的入口(在Spring中,为Dispatcher类)
public abstract class AbstractService {
protected abstract void register();
protected abstract Object receive(String methodId, Object[] params);
}
// 服务B 提供展示功能,同时调用服务A 执行记录
public class ServiceB extends AbstractService{
private Mediator mediator;
public ServiceB(){}
@Override
protected void register() {
mediator = Mediator.getInstance();
mediator.register("ServiceB",this);
}
@Override
protected Object receive(String methodId, Object[] params) {
if("show".equals(methodId)){
show(params);
}
return null;
}
private void show(Object[] params){
System.out.println("ServiceB - 执行ServiceB.show功能");
System.out.println("ServiceB - 申请serviceA.record()方法");
mediator.relay("ServiceA","record",params);
}
}
public class Test {
public static void main(String[] args) {
Mediator mediator = Mediator.getInstance();
new ServiceA().register();
new ServiceB().register();
mediator.relay("ServiceB","show",new Object[]{"String"});
}
}
// Mediator.relay() - ServiceB.show()
// ServiceB - 执行ServiceB.show功能
// ServiceB - 申请serviceA.record()方法
// Mediator.relay() - ServiceA.record()
// ServiceA - 执行ServiceA.record功能
欢迎疑问、期待评论、感谢指点 -- kiqi,愿同您为友
-- 星河有灿灿,愿与之辉