简介

中介者模式:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

我们来举个例子:

机场的飞机降落起飞,都是需要通过塔台进行调度的,如果没有塔台的调度,5架飞机之间需要相互通信确认,以免出现问题,但是如果这么做,一定会出现问题,我们可以看下他们此时的关系网络。

每一架飞机都要和其他4架飞机进行沟通通讯,如果这个关系网放在代码上去实现,这是非常难看的,这代码神仙看了都得摇头。

而中介者就是为了解决这种网状的关系,通过增加一个中介对象,大家都通过中介对象进行通信,从而将飞机1对4的情况转为1对1的。

具体的做法呢稍后看代码。

中介者模式和观察者模式非常相似,同样都是:1对多的关系,都会收集对象的通知方法,统一管理,但是他们还是有不同的。

中介者处理的是群体之间的消息通信(解耦),也就是说,某一个对象改变可以通过中介者通知所有人,所以他是没有具体的被观察的数据的,和观察者不一样。

观察者模式是一种单向的,只能通过观察者观察到变化再去通知,而不是像中介者模式这样,任何对象都可以通知所有人。(好比上课,只能老师授课给班上所有的学生,反过来不行)

现在知道中介者模式的用法,我们就可以继续往下看,它的角色:

  1. 抽象的中介者:用于定义具体中介者的接口,提供了对象注册进来和统一转发消息的抽象方法
  2. 具体的中介者:实现抽象的接口,通过一个列表对象,如array这些来管理注册进来的对象,协调他们之间的关系,所以它依赖于注册进来的对象的抽象、
  3. 抽象的注册的对象:定义接口,保存具体的中介者,因为到时候需要通过中介者来通知其他对象,
  4. 具体的注册对象:实现抽象的接口,实现具体的交互逻辑

代码实现

//抽象的中介者:主要还是用来给添加进来的对象进行依赖用
abstract class Broker {
  //添加一个对象到列表
  public abstract add(a: A): void;

  //通知所有的对象更新了,注意需要排除调用者
  public abstract notify(a: A): void;
}

//具体的中介者
class MyBorker extends Broker {
  private list: Array<A> = [];

  public add(a: A): void {
    if (!this.list.includes(a)) {
      this.list.push(a);
    }
  }

  public notify(a: A): void {
    this.list
      .filter((item) => item !== a)
      .forEach((item) => {
        item.update();
      });
  }
}

//抽象的对象类
abstract class A {
  //保存中介者
  protected broker: Broker;

  constructor(broker: Broker) {
    this.broker = broker;
  }

  //收到更新通知
  abstract update(): void;

  //通知其他人我变化了
  abstract notifyOthers(): void;
}

//具体的对象B
class B extends A {
  constructor(broker: Broker) {
    super(broker);
  }

  update(): void {
    console.log("触发了B的更新");
  }

  notifyOthers(): void {
    console.log("我通知其他人我更新了");
    this.broker.notify(this);
  }
}

//具体的对象C
class C extends A {
  constructor(broker: Broker) {
    super(broker);
  }

  update(): void {
    console.log("触发了C的更新");
  }

  notifyOthers(): void {
    console.log("我通知其他人我更新了");
    this.broker.notify(this);
  }
}

//客户使用
class Client {
  constructor() {
    //中介者
    const broker = new MyBorker();
    //具体的对象
    const b = new B(broker);
    const c = new C(broker);

    //添加对象到中介者
    broker.add(b);
    broker.add(c);

    //b通知其他人更新了
    b.notifyOthers();

    //c通知其他人更新了
    c.notifyOthers();
  }
}

new Client();

其实中介者模式还有一个很好理解的例子,那就是聊天室,比如qq群聊,我们在群里发送一条消息,然后所有人都能收到我的消息,但是呢,我并不需要一个个去通知群里的人,我也不需要加他们的好友,群其实就成为了一个中介者,中介者只用关心谁进来谁出去了,我注册它到到队列里,我从队列里删除出去的人,有人更新了,触发群的发送消息功能通知所有人。

应用场景

  • 当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时。
  • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

模式扩展

在实际开发中,通常采用以下两种方法来简化中介者模式,使开发变得更简单。

  1. 不定义中介者接口,把具体中介者对象实现成为单例。
  2. 同事对象不持有中介者,而是在需要的时候直接获取中介者对象并调用。

从js角度,中介者单例,然后export导出,需要用它的对象通过import引入使用,而不需要持有它。

分类: 设计模式 标签: 设计模式行为模式解耦中介者模式群聊中介网状

评论

暂无评论数据

暂无评论数据

目录