中介者模式是一种行为型设计模式,它允许对象之间相互交互,而不必直接相互依赖。在这个模式中,对象通过一个中介者对象来协调彼此之间的通信。中介者模式能够降低对象之间的耦合度,使系统更易于维护和扩展。
下面我们来详细了解中介者模式的实现和应用。
1. 中介者模式的定义
中介者模式(Mediator Pattern)是定义了一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示的相互引用,从而使其耦合性松散,而且可以独立地改变它们之间的交互。
2. 中介者模式的结构
中介者模式包含以下几个部分:
- 中介者(Mediator):定义了各个同事对象之间交互的接口,并负责协调各个同事之间的关系。
- 具体中介者(Concrete Mediator):实现中介者接口,协调各个同事之间的关系。
- 同事对象(Colleague):定义了各个同事对象之间交互的接口,每个同事对象都知道中介者对象。
- 具体同事对象(Concrete Colleague):实现同事接口,每个同事对象都会与其他同事对象交互,但是只与中介者对象交互。
3. 中介者模式的实现
在中介者模式中,所有的对象都是同等的,没有谁是主导者,也没有谁是被动者,它们只是通过一个中介者来进行交互。这里我们以一个简单的例子来说明中介者模式的实现。
假设我们有一个聊天室的程序,其中有多个用户同时在线,每个用户都可以发送消息给其他在线用户。在这种情况下,我们可以使用中介者模式来实现聊天室的功能。
首先我们定义一个中介者接口,用来协调用户之间的消息发送。
```javascript
// 定义中介者接口
class Mediator {
send(message, sender) {}
}
```
然后我们实现一个具体的中介者对象,用来协调各个用户之间的消息发送。
```javascript
// 实现具体的中介者对象
class ChatRoomMediator extends Mediator {
constructor() {
super();
this.users = new Set();
}
addUser(user) {
this.users.add(user);
}
send(message, sender) {
for (let user of this.users) {
if (user !== sender) {
user.receive(message);
}
}
}
}
```
中介者模式是一种行为型设计模式,它允许对象相互交互,而不必显式地相互引用。这种模式通过将对象间的通信转化为中介者对象的一对多关系来实现。中介者对象允许各个对象独立地交互,从而减少了耦合度,使得代码更加灵活、易于维护和扩展。
在中介者模式中,各个对象不再相互引用,而是通过中介者对象进行通信。当一个对象需要与另一个对象交互时,它不会直接调用另一个对象的方法,而是向中介者对象发出请求。中介者对象将请求传递给其他相关对象,并负责协调各个对象之间的交互。
以下是一个简单的中介者模式示例:
```javascript
class Mediator {
constructor() {
this.colleagues = [];
}
addColleague(colleague) {
this.colleagues.push(colleague);
}
send(message, sender) {
for (let i = 0; i < this.colleagues.length; i++) {
if (this.colleagues[i] !== sender) {
this.colleagues[i].receive(message);
}
}
}
}
class Colleague {
constructor(mediator) {
this.mediator = mediator;
this.mediator.addColleague(this);
}
send(message) {
this.mediator.send(message, this);
}
receive(message) {
console.log(`Received message: ${message}`);
}
}
const mediator = new Mediator();
const colleague1 = new Colleague(mediator);
const colleague2 = new Colleague(mediator);
colleague1.send('Hello, colleague 2!');
colleague2.send('Hello, colleague 1!');
```
在上面的示例中,`Mediator` 是中介者类,负责协调各个同事对象之间的交互。`Colleague` 是同事类,用于与其他同事对象交互。当同事对象发送消息时,它会通过中介者对象将消息发送给其他同事对象,从而实现了相互交互的目的。
需要注意的是,在中介者模式中,同事对象并不直接相互引用,而是通过中介者对象进行通信,这样可以使得对象之间的耦合度降低,从而使得代码更加灵活、易于维护和扩展。同时,由于中介者对象负责协调对象之间的交互,因此它可以提高代码的可读性和可维护性。// 定义具体的同事类B
class ColleagueB extends Colleague {
constructor(mediator) {
super(mediator);
this.name = 'B';
}
// 发送信息时通知中介者
send(message) {
this.mediator.send(message, this);
}
// 接收信息
receive(message) {
console.log(`${this.name} received message: ${message}`);
}
}
// 定义具体的中介者类
class ConcreteMediator extends Mediator {
constructor() {
super();
this.colleagueA = null;
this.colleagueB = null;
}
// 注册同事对象
register(colleague) {
if (colleague instanceof ColleagueA) {
this.colleagueA = colleague;
} else if (colleague instanceof ColleagueB) {
this.colleagueB = colleague;
}
}
// 根据对象发送信息
send(message, colleague) {
if (colleague === this.colleagueA) {
this.colleagueB.receive(message);
} else if (colleague === this.colleagueB) {
this.colleagueA.receive(message);
}
}
}
// 测试代码
const mediator = new ConcreteMediator();
const colleagueA = new ColleagueA(mediator);
const colleagueB = new ColleagueB(mediator);
mediator.register(colleagueA);
mediator.register(colleagueB);
colleagueA.send('Hello, B!');
colleagueB.send('Hi, A!');
5. 实现中介者模式
在中介者模式中,我们需要实现一个中介者对象,该对象承担着协调各个对象之间的责任。在本例中,我们可以定义一个 `Mediator` 对象,用于协调 `Employee` 和 `Manager` 对象之间的通信。在这个 `Mediator` 对象中,我们需要实现以下功能:
- 注册对象:当一个对象被创建时,需要将其注册到中介者对象中,以便协调其与其他对象之间的通信。
- 通信协调:当一个对象需要与其他对象进行通信时,需要将消息发送给中介者对象,由中介者对象协调其与其他对象之间的通信。
下面是一个简单的 `Mediator` 对象实现,该对象能够实现上述功能:
```javascript
class Mediator {
constructor() {
this.employees = [];
this.managers = [];
}
registerEmployee(employee) {
this.employees.push(employee);
}
registerManager(manager) {
this.managers.push(manager);
}
sendMessage(sender, message) {
if (this.employees.includes(sender)) {
this.managers.forEach((manager) => {
manager.receiveMessage(message);
});
} else if (this.managers.includes(sender)) {
this.employees.forEach((employee) => {
employee.receiveMessage(message);
});
}
}
}
```
在上面的实现中,我们定义了一个 `Mediator` 对象,并在其构造函数中初始化了两个空数组 `employees` 和 `managers`,用于存储已注册的 `Employee` 和 `Manager` 对象。同时,我们还实现了 `registerEmployee` 和 `registerManager` 方法,用于将 `Employee` 和 `Manager` 对象注册到中介者对象中。最后,我们还实现了 `sendMessage` 方法,用于实现对象之间的通信协调。在该方法中,我们首先判断消息发送者是 `Employee` 对象还是 `Manager` 对象,然后将消息发送给对应的接收者对象。
6. 实现对象
现在我们已经定义了中介者对象和具体的对象类型,接下来我们需要实现这些对象。在本例中,我们需要实现 `Employee` 和 `Manager` 对象,并将它们注册到中介者对象中,以便实现对象之间的通信。
```javascript
class Employee {
constructor(name, mediator) {
this.name = name;
this.mediator = mediator;
this.mediator.registerEmployee(this);
}
sendMessage(message) {
this.mediator.sendMessage(this, message);
}
receiveMessage(message) {
console.log(`${this.name} received message: ${message}`);
}
}
class Manager {
constructor(name, mediator) {
this.name = name;
this.mediator = mediator;
this.mediator.registerManager(this);
}
sendMessage(message) {
this.mediator.sendMessage(this, message);
}
receiveMessage(message) {
console.log(`${this.name} received message: ${message}`);
}
}
```
接受中介者对象作为参数,以便它们可以访问中介者对象。然后,在中介者对象中定义一个方法,用于注册和移除同事对象。这个方法会维护一个同事对象列表。接下来,在中介者对象中定义一个方法,用于处理同事对象的交互,以便它们可以通过中介者对象相互通信。
下面是一个简单的示例:
```javascript
class Mediator {
constructor() {
this.colleagues = [];
}
register(colleague) {
if (!this.colleagues.includes(colleague)) {
this.colleagues.push(colleague);
colleague.setMediator(this);
}
}
unregister(colleague) {
const index = this.colleagues.indexOf(colleague);
if (index !== -1) {
this.colleagues.splice(index, 1);
colleague.setMediator(null);
}
}
notify(sender, event) {
this.colleagues.forEach(colleague => {
if (colleague !== sender) {
colleague.receiveEvent(event);
}
});
}
}
class Colleague {
constructor() {
this.mediator = null;
}
setMediator(mediator) {
this.mediator = mediator;
}
sendEvent(event) {
this.mediator.notify(this, event);
}
receiveEvent(event) {
console.log(`${this.constructor.name} received event: ${event}`);
}
}
class ConcreteColleagueA extends Colleague {
constructor() {
super();
}
sendSomeEvent() {
console.log(`${this.constructor.name} sent event`);
this.sendEvent('some event');
}
}
class ConcreteColleagueB extends Colleague {
constructor() {
super();
}
receiveEvent(event) {
if (event === 'some event') {
console.log(`${this.constructor.name} received some event`);
} else {
super.receiveEvent(event);
}
}
}
const mediator = new Mediator();
const colleagueA = new ConcreteColleagueA();
const colleagueB = new ConcreteColleagueB();
mediator.register(colleagueA);
mediator.register(colleagueB);
colleagueA.sendSomeEvent(); // Output: ConcreteColleagueA sent event, ConcreteColleagueB received some event
mediator.unregister(colleagueB);
colleagueA.sendSomeEvent(); // Output: ConcreteColleagueA sent event
```
在上面的示例中,`Mediator`类是中介者对象,`Colleague`类是同事对象。同事对象可以通过`setMediator`方法将中介者对象设置为它们自己的属性。`Colleague`类中的`sendEvent`方法用于将事件发送给中介者对象。中介者对象可以通过`notify`方法将事件广播给所有同事对象。
在这个示例中,`ConcreteColleagueA`和`ConcreteColleagueB`是具体的同事对象。`ConcreteColleagueA`类中的`sendSomeEvent`方法用于发送一个事件。当`ConcreteColleagueB`收到这个事件时,它会输出一条消息。如果中介者对象被删除,`ConcreteColleagueB`将不再接收事件。