中介者模式

1,094 阅读2分钟

前言

中介者模式,平常很容易会使用到,本质是封装了不同对象的交互细节,而不是直接交互,承担的职责很多,但是通信效率其实反而变差了。

目录

一、定义

用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

二、模式原理分析

//通用抽象中介者
public abstract class Mediator{
    //定义组件类
    protected ConcreteComponent1 c1;
    protected ConcreteComponent2 c2;
    public ConcreteComponent1 getC1(){
        return c1;
    }
    public ConcreteComponent2 getC2(){
        return c2;
    }
    public void setC1(ConcreteComponent1 c1){
        this.c1 = c1;
    }
    public void setC2(ConcreteComponent2 c2){
        this.c2 = c2;
    }
    //中介者模式地业务逻辑
    public abstract void doSomething1();
    public abstract void doSomething2();
}
//通用中介者
public class ConcreteMediator extends Mediator{
    @Override
    public void doSomething1(){
        //调用组件类的方法
        super.c1.selfMethod1();
        super.c2.selfMethod2();
    }
    public void doSomething2(){
        super.c1.selfMethod1();
        super.c2.selfMethod2();
    }
}
//抽象组件类
public abstract class Component{
    protected Mediator mediator;
    piublic Component(Mediator _mediator){
        this.mediator = _mediator;
    }
}
//具体组件类
public class ConcreteComponent1 extends Component{
    public ConcreteComponent1(Mediator _mediator){
        super(_mediator);
    }
    public void selfMethod1(){
        //自己的业务逻辑
    }
    public void depMethod1(){
        //自己的业务逻辑
        super.mediator.doSomething1();
    }
}

从模板代码中应该可以看出,中介者对象就是用于处理对象与对象之间的直接交互,封装了多个对象之间的交互细节。

举个例子,聊天室发送消息的功能

//抽象的聊天室类
public interface ChatRoom {
    void sendMessage(String msg, String userId);
    void addUser(User user);
}
//具体的聊天室类
public class ChatRoomImpl implements ChatRoom {

    private Map<String, User> usersMap = new HashMap<>();

    @Override
    public void sendMessage(String msg, String userId) {
        User u = usersMap.get(userId);
        u.receive(msg);
    }

    @Override
    public void addUser(User user) {
        this.usersMap.put(user.getId(), user);
    }
}
//抽象的组件类
public abstract class User {

    private ChatRoom mediator;
    private String id;
    private String name;

    public User(ChatRoom room, String id, String name){
        this.mediator = room;
        this.name = name;
        this.id = id;
    }

    public abstract void send(String msg, String userId);

    public abstract void receive(String msg);

    public ChatRoom getMediator() {
        return mediator;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}
//具体的组件类
public class ChatUser extends User {

    public ChatUser(ChatRoom room, String id, String name) {
        super(room, id, name);
    }

    @Override
    public void send(String msg, String userId) {
        System.out.println(this.getName() + " :: Sending Message : " + msg);
        getMediator().sendMessage(msg, userId);
    }

    @Override
    public void receive(String msg) {
        System.out.println(this.getName() + " :: Received Message : " + msg);
    }
}

三、使用场景

  • 当在类图中出现了蜘蛛网状结构,可以考虑使用中介者模式,梳理为星型结构

  • 系统中对象之间存在复杂的引用关系时

  • 通过一个中间对象来封装多个类中的共有行为时

四、优点

  • 减少对象之间的直接交互,间接解耦过多依赖

  • 减少子类的创建数量,简化系统的设计和实现

  • 通过中间层,可以实现快速扩展,提升代码扩展性

五、缺点

  • 中间层,即中介者类的交互逻辑可能比较复杂,后续难以维护

  • 中介者演变承了新的重度依赖对象

  • 中介者需要知道所有对象交互的逻辑