就像一辆汽车的行驶系统,在中介者模式中,你只需要在车内发出广播(到站啦、停车啦、上车啦...请文明乘车尊老爱幼啦...),而不用关心谁在车上,谁要上车谁要下车,他们自己根据广播做自己要做的事,哪怕他不听广播,听了也不做自己要做的事都无所谓。
通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用,降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互。
观察者模式和中介者模式都是通过消息收发机制实现,不过在观察者模式中,一个对象既可以是消息的发送者也可以是消息的接收者,而中介者模式中消息的发送方只有一个就是中介者对象,而且中介者对象不能订阅消息,只有那些活跃对象(订阅者)才能订阅中介者消息。
// 汽车 class Bus { constructor() { // 初始化所有乘客 this.passengers = {} } // 发布广播 broadcast(passenger, message = passenger) { // 如果车上有乘客 if (Object.keys(this.passengers).length) { // 如果是针对某个乘客发的,就单独给他听 if (passenger.id && passenger.listen) { // 乘客他爱听不听 if (this.passengers[passenger.id]) { this.passengers[passenger.id].listen(message) } // 不然就广播给所有乘客 } else { Object.keys(this.passengers).forEach(passenger => { if (this.passengers[passenger].listen) { this.passengers[passenger].listen(message) } }) } } } // 乘客上车 aboard(passenger) { this.passengers[passenger.id] = passenger } // 乘客下车 debus(passenger) { this.passengers[passenger.id] = null delete this.passengers[passenger.id] console.log(`乘客${passenger.id}下车`) } // 开车 start() { this.broadcast({ type: 1, content: '前方无障碍,开车!Over'}) } // 停车 end() { this.broadcast({ type: 2, content: '老司机翻车,停车!Over'}) } } // 乘客 class Passenger { constructor(id) { this.id = id } // 听广播 listen(message) { console.log(`乘客${this.id}收到消息`, message) // 乘客发现停车了,于是自己下车 if (Object.is(message.type, 2)) { this.debus() } } // 下车 debus() { console.log(`我是乘客${this.id},我现在要下车`, bus) bus.debus(this) } } // 创建一辆汽车 const bus = new Bus() // 创建两个乘客 const passenger1 = new Passenger(1) const passenger2 = new Passenger(2) // 俩乘客分别上车 bus.aboard(passenger1) bus.aboard(passenger2) // 2秒后开车 setTimeout(bus.start.bind(bus), 2000) // 3秒时司机发现2号乘客没买票,2号乘客被驱逐下车 setTimeout(() => { bus.broadcast(passenger2, { type: 3, content: '同志你好,你没买票,请下车!' }) bus.debus(passenger2) }, 3000) // 4秒后到站停车 setTimeout(bus.end.bind(bus), 3600) // 6秒后再开车,车上已经没乘客了 setTimeout(bus.start.bind(bus), 6666)
在中介者模式中,订阅者是单向的,只能是订阅者而不能是发布者。而消息统一由中介者对象发布。