程序员子龙(Java面试 + Java学习) 程序员子龙(Java面试 + Java学习)
首页
学习指南
工具
开源项目
技术书籍

程序员子龙

Java 开发从业者
首页
学习指南
工具
开源项目
技术书籍
  • 基础

  • JVM

  • Spring

  • 并发编程

  • Mybatis

  • 网络编程

  • 数据库

  • 缓存

  • 设计模式

    • 单例模式
    • 工厂模式
    • 观察者模式
    • 简单工厂模式
    • 建造者模式
    • 模板设计模式
    • 使用策略+工厂模式彻底干掉代码中的if else
    • 责任链设计模式
    • 中介者模式
      • 核心思想
      • 本质
        • 实现简单的中介者模式
        • 应用场景
        • 优点
        • 缺点
        • 应用
      • 总结
  • 分布式

  • 高并发

  • SpringBoot

  • SpringCloudAlibaba

  • Nginx

  • 面试

  • 生产问题

  • 系统设计

  • 消息中间件

  • Java
  • 设计模式
程序员子龙
2024-01-29
目录

中介者模式

# 中介者模式

# 定义

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

从类图中看,中介者模式由以下几部分组成:

  • Mediator 抽象中介者角色

    抽象中介者角色定义统一的接口,用于各同事角色之间的通信。

  • Concrete Mediator 具体中介者角色

    具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。

  • Colleague 抽象同事类

    定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

    每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法(Dep-Method)。

  • Concrete Colleague 同事角色

抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

# 核心思想

如果一个系统中对象之间的联系呈现出网状结构,对象之间存在大量多对多关系,将导致关系及其复杂,这些对象称为 "同事对象"。我们可以引入一个中介者对象,使各个同事对象只跟中介者对象打交道,将同事对象之间的关系行为进行分离和封装,使之成为一个松耦合的系统。

# 本质

解耦各个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道。通过中介者对象统一管理这些交互关系,并且还可以在同事对象的逻辑上封装自己的逻辑。

# 实现简单的中介者模式

模拟同事之间发送、接收消息

每一个同事角色都知道中介者角色,而且与其它的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分两种:一种是同事本身行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为,与其它同事类或者中介者没有任何依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法。

/**
 * 抽象同事类
 * @version 1.0.0
 * @date 2021/11/25 17:31
 */
public abstract class Colleague {

    protected Mediator mediator;

    public void setMedium(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void receive();

    public abstract void send();

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

抽象中介者角色定义统一的接口,用于各同事角色之间的通信。

/**
 * 抽象中介者
 * @version 1.0.0
 * @date 2021/11/25 17:30
 */
public abstract class Mediator {

    public abstract void register(Colleague colleague);


    public abstract void relay(Colleague colleague);
}
1
2
3
4
5
6
7
8
9
10
11
12

具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。

/**
 * 具体中介者
 * @version 1.0.0
 * @date 2021/11/25 17:46
 */
public class ConcreteMediator extends Mediator{

    private List<Colleague> colleagues = new ArrayList<Colleague>();

    @Override
    public void register(Colleague colleague) {
        if (!colleagues.contains(colleague)) {
            colleagues.add(colleague);
            colleague.setMedium(this);
        }
    }

    @Override
    public void relay(Colleague cl) {
        for (Colleague ob : colleagues) {
            if (!ob.equals(cl)) {
                ob.receive();
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

同事类必须有中介者,而中介者却可以只有部分同事类。

/**
 * 具体同事1
 * @version 1.0.0
 * @date 2021/11/25 17:37
 */
public class ConcreteColleague1 extends Colleague{

    @Override
    public void receive() {
        System.out.println("具体同事类1收到请求。");
    }

    @Override
    public void send() {
        System.out.println("具体同事类1发出请求。");
        //请中介者转发
        mediator.relay(this);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 具体同事2
 * @version 1.0.0
 * @date 2021/11/25 18:00
 */
public class ConcreteColleague2 extends Colleague{

    @Override
    public void receive() {
        System.out.println("具体同事类2收到请求。");

    }

    @Override
    public void send() {
        System.out.println("具体同事类2发出请求。");
        //请中介者转发
        mediator.relay(this);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

输出结果

具体同事类1发出请求。

具体同事类2收到请求。

具体同事类2发出请求。 具体同事类1收到请求。

# 应用场景

  1. 何时使用
  • 多个类相互耦合,形成网状结构时
  1. 方法
  • 将网状结构分离为星型结构

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

  • 想通过一个中间类来封装多个类的行为,而又不想生成太多的子类

# 优点

中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然同时也降低了类间的耦合。类之间各司其职,符合迪米特法则

# 缺点

中介者模式的缺点就是中介者会膨胀得很大,而且逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就越复杂。

# 应用

/**
 * 抽象中介者
 */
public interface Mediator {

    void register(String dname,Department d);

    void command(String dname);
}
1
2
3
4
5
6
7
8
9
/**
 * 抽象同事类
 */
public interface Department {

    // 做本部门的事情
    void selfAction();
    // 向总经理发出申请
    void outAction();
}
1
2
3
4
5
6
7
8
9
10
/**
 * 具体中介者  总经理
 */
public class President implements Mediator{

    private Map<String,Department> map = new HashMap    <String , Department>();

    @Override
    public void command(String dname) {
        // 在不改变同事类的情况下,封装一些公共的逻辑
        System.out.println("执行前-----打印日志信息");
        map.get(dname).selfAction();
        System.out.println("执行后-----打印日志信息");
    }

    @Override
    public void register(String dname, Department d) {
        map.put(dname, d);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 具体同事类 财务
 */
public class Finacial implements Department {

    // 持有中介者(总经理)的引用
    private Mediator m;

    public Finacial(Mediator m) {
        super();
        this.m = m;
        m.register("finacial", this);
    }

    @Override
    public void outAction() {
        System.out.println("汇报工作!没钱了");
    }

    @Override
    public void selfAction() {
        System.out.println("管理财务");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * 具体同事类 市场部
 */
public class Market  implements Department {

    // 持有中介者(总经理)的引用
    private Mediator m;

    public Market(Mediator m) {
        super();
        this.m = m;
        m.register("market", this);
    }

    @Override
    public void outAction() {
        System.out.println("汇报项目承接的进度,需要资金支持");
        // 通过中介者调用同事类,并没有和同事类耦合。
        m.command("finacial");
    }

    @Override
    public void selfAction() {
        System.out.println("谈项目");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

客户端测试:

public class Client {

    public static void main(String[] args) {
        Mediator m = new President();

        Market market = new Market(m);
        Finacial f = new Finacial(m);

        market.selfAction();
        market.outAction();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

输出结果

谈项目 汇报项目承接的进度,需要资金支持 执行前-----打印日志信息 管理财务 执行后-----打印日志信息

# 总结

中介者模式其实就是将一个复杂的事分离出来统一管理,将同事对象之间的关系行为进行分离和封装。

上次更新: 2024/01/30, 15:08:57
责任链设计模式
分布式系统基础知识

← 责任链设计模式 分布式系统基础知识→

最近更新
01
一个注解,优雅的实现接口幂等性
11-17
02
MySQL事务(超详细!!!)
10-14
03
阿里二面:Kafka中如何保证消息的顺序性?这周被问到两次了
10-09
更多文章>
Theme by Vdoing | Copyright © 2024-2024

    辽ICP备2023001503号-2

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式