1. 设计模式原理说明
中介者模式(Mediator Pattern) 是一种行为设计模式,它使用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式将多对多的关系转化为一对多的关系,减少了类间的直接依赖,降低了系统的复杂度。
主要角色
- Mediator(中介者):定义了同事对象用来与中介者通信的接口。
- ConcreteMediator(具体中介者):通过协调各个同事对象实现协作行为。它知道所有的同事对象,并从同事对象接收消息,然后向其他同事对象转发消息。
- Colleague(同事类):每个同事类都知道中介者,但不知道其他同事。同事可以通过中介者与其他同事通信。
2. UML 类图及解释
UML 类图
+-----------------+
| Mediator |
|-----------------|
| + send(message: String, colleague: Colleague) |
+-----------------+
^
|
|
v
+-----------------+
| ConcreteMediator|
|-----------------|
| - colleagues: List<Colleague> |
| + send(message: String, colleague: Colleague) |
+-----------------+
+-----------------+
| Colleague |
|-----------------|
| - mediator: Mediator |
| + setMediator(mediator: Mediator) |
| + send(message: String) |
| + receive(message: String) |
+-----------------+
^
|
|
v
+-----------------+
| ConcreteColleagueA|
|-----------------|
| + send(message: String) |
| + receive(message: String) |
+-----------------+
^
|
|
v
+-----------------+
| ConcreteColleagueB|
|-----------------|
| + send(message: String) |
| + receive(message: String) |
+-----------------+
类图解释
- Mediator:定义了一个接口,用于与同事对象通信。它提供了一个
send
方法,同事对象通过这个方法发送消息。 - ConcreteMediator:实现了中介者接口。它维护了一组同事对象,并负责协调这些对象之间的通信。
- Colleague:定义了一个接口,用于设置中介者和发送/接收消息。每个同事对象都知道中介者,但不知道其他同事。
- ConcreteColleagueA 和 ConcreteColleagueB:实现了同事接口,它们通过中介者发送和接收消息。
3. 代码案例及逻辑详解
Java 代码案例
// 中介者接口
interface Mediator {
void send(String message, Colleague colleague);
}
// 具体中介者
class ConcreteMediator implements Mediator {
private List<Colleague> colleagues = new ArrayList<>();
public void add(Colleague colleague) {
colleagues.add(colleague);
}
@Override
public void send(String message, Colleague colleague) {
for (Colleague col : colleagues) {
if (col != colleague) {
col.receive(message);
}
}
}
}
// 同事接口
interface Colleague {
void setMediator(Mediator mediator);
void send(String message);
void receive(String message);
}
// 具体同事 A
class ConcreteColleagueA implements Colleague {
private Mediator mediator;
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
public void send(String message) {
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println("ColleagueA receives: " + message);
}
}
// 具体同事 B
class ConcreteColleagueB implements Colleague {
private Mediator mediator;
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
@Override
public void send(String message) {
mediator.send(message, this);
}
@Override
public void receive(String message) {
System.out.println("ColleagueB receives: " + message);
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
Colleague colleagueA = new ConcreteColleagueA();
Colleague colleagueB = new ConcreteColleagueB();
colleagueA.setMediator(mediator);
colleagueB.setMediator(mediator);
mediator.add(colleagueA);
mediator.add(colleagueB);
colleagueA.send("Hello from A");
colleagueB.send("Hello from B");
}
}
C++ 代码案例
#include <iostream>
#include <vector>
#include <memory>
// 中介者接口
class Mediator {
public:
virtual void send(const std::string& message, Colleague* colleague) = 0;
};
// 具体中介者
class ConcreteMediator : public Mediator {
private:
std::vector<Colleague*> colleagues;
public:
void add(Colleague* colleague) {
colleagues.push_back(colleague);
}
void send(const std::string& message, Colleague* colleague) override {
for (auto col : colleagues) {
if (col != colleague) {
col->receive(message);
}
}
}
};
// 同事接口
class Colleague {
protected:
Mediator* mediator;
public:
void setMediator(Mediator* mediator) {
this->mediator = mediator;
}
virtual void send(const std::string& message) = 0;
virtual void receive(const std::string& message) = 0;
};
// 具体同事 A
class ConcreteColleagueA : public Colleague {
public:
void send(const std::string& message) override {
mediator->send(message, this);
}
void receive(const std::string& message) override {
std::cout << "ColleagueA receives: " << message << std::endl;
}
};
// 具体同事 B
class ConcreteColleagueB : public Colleague {
public:
void send(const std::string& message) override {
mediator->send(message, this);
}
void receive(const std::string& message) override {
std::cout << "ColleagueB receives: " << message << std::endl;
}
};
// 客户端
int main() {
Mediator* mediator = new ConcreteMediator();
Colleague* colleagueA = new ConcreteColleagueA();
Colleague* colleagueB = new ConcreteColleagueB();
colleagueA->setMediator(mediator);
colleagueB->setMediator(mediator);
mediator->add(colleagueA);
mediator->add(colleagueB);
colleagueA->send("Hello from A");
colleagueB->send("Hello from B");
delete mediator;
delete colleagueA;
delete colleagueB;
return 0;
}
Python 代码案例
from abc import ABC, abstractmethod
# 中介者接口
class Mediator(ABC):
@abstractmethod
def send(self, message, colleague):
pass
# 具体中介者
class ConcreteMediator(Mediator):
def __init__(self):
self.colleagues = []
def add(self, colleague):
self.colleagues.append(colleague)
def send(self, message, colleague):
for col in self.colleagues:
if col != colleague:
col.receive(message)
# 同事接口
class Colleague(ABC):
def __init__(self, mediator):
self.mediator = mediator
@abstractmethod
def send(self, message):
pass
@abstractmethod
def receive(self, message):
pass
# 具体同事 A
class ConcreteColleagueA(Colleague):
def send(self, message):
self.mediator.send(message, self)
def receive(self, message):
print(f"ColleagueA receives: {message}")
# 具体同事 B
class ConcreteColleagueB(Colleague):
def send(self, message):
self.mediator.send(message, self)
def receive(self, message):
print(f"ColleagueB receives: {message}")
# 客户端
if __name__ == "__main__":
mediator = ConcreteMediator()
colleagueA = ConcreteColleagueA(mediator)
colleagueB = ConcreteColleagueB(mediator)
mediator.add(colleagueA)
mediator.add(colleagueB)
colleagueA.send("Hello from A")
colleagueB.send("Hello from B")
Go 代码案例
package main
import (
"fmt"
)
// 中介者接口
type Mediator interface {
send(message string, colleague Colleague)
}
// 具体中介者
type ConcreteMediator struct {
colleagues []Colleague
}
func (m *ConcreteMediator) add(colleague Colleague) {
m.colleagues = append(m.colleagues, colleague)
}
func (m *ConcreteMediator) send(message string, colleague Colleague) {
for _, col := range m.colleagues {
if col != colleague {
col.receive(message)
}
}
}
// 同事接口
type Colleague interface {
setMediator(mediator Mediator)
send(message string)
receive(message string)
}
// 具体同事 A
type ConcreteColleagueA struct {
mediator Mediator
}
func (c *ConcreteColleagueA) setMediator(mediator Mediator) {
c.mediator = mediator
}
func (c *ConcreteColleagueA) send(message string) {
c.mediator.send(message, c)
}
func (c *ConcreteColleagueA) receive(message string) {
fmt.Printf("ColleagueA receives: %s\n", message)
}
// 具体同事 B
type ConcreteColleagueB struct {
mediator Mediator
}
func (c *ConcreteColleagueB) setMediator(mediator Mediator) {
c.mediator = mediator
}
func (c *ConcreteColleagueB) send(message string) {
c.mediator.send(message, c)
}
func (c *ConcreteColleagueB) receive(message string) {
fmt.Printf("ColleagueB receives: %s\n", message)
}
// 客户端
func main() {
mediator := &ConcreteMediator{}
colleagueA := &ConcreteColleagueA{}
colleagueB := &ConcreteColleagueB{}
colleagueA.setMediator(mediator)
colleagueB.setMediator(mediator)
mediator.add(colleagueA)
mediator.add(colleagueB)
colleagueA.send("Hello from A")
colleagueB.send("Hello from B")
}
4. 总结
中介者模式 是一种行为设计模式,它使用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
主要优点
- 降低对象间的耦合度:通过引入中介者对象,将原本直接依赖的对象间关系解耦,使得对象间的通信更加简单。
- 简化对象之间的通信:中介者对象集中管理对象间的通信,使得对象之间的通信更加方便和灵活。
- 易于扩展:新增加的对象只需要与中介者交互,而不需要修改其他对象的代码。
主要缺点
- 中介者对象可能变得臃肿:如果系统中有很多对象需要交互,中介者对象可能会变得非常复杂,难以维护。
- 增加了系统的复杂性:引入中介者对象会增加系统的复杂性,特别是在小型系统中,这种模式可能会显得过于重载。
适用场景
- 当一组对象以定义良好但复杂的方式进行通信时,可以通过引入中介者对象来简化这些通信。
- 当需要在运行时动态地改变对象间的通信时,可以通过中介者对象来实现。
- 当对象间的通信逻辑发生变化时,可以通过修改中介者对象来实现,而不需要修改具体的对象类。