设计模式 17
- 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
- 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
- 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式
中介者模式(Mediator Pattern)
1 定义
中介者模式将系统中多个对象之间复杂的交互和依赖关系抽象为一个中介者对象,各个对象不直接引用彼此,而是通过中介者进行通信。这样做可以减少对象之间的直接依赖,从而使系统更加易于维护和扩展。
2 结构
中介者模式包含以下角色:
- 中介者接口(Mediator): 定义一个接口用于与各同事对象通信。
- 具体中介者(ConcreteMediator): 实现中介者接口,协调各同事对象之间的交互。
- 同事类(Colleague): 每个同事类都知道中介者对象,并且在需要与其他同事通信时,都会通过中介者。
UML 类图
+---------------------------------------------------+
| Mediator |
+---------------------------------------------------+
| + Notify(sender: Colleague, event: string): void |
+---------------------------------------------------+
^
|
+---------------------------------------------------+
|ConcreteMediator |
+---------------------------------------------------+
| + Notify(sender: Colleague, event: string): void |
| + RegisterColleague(colleague: Colleague): void |
+---------------------------------------------------+
+-------------------------------------------+
| Colleague |
+-------------------------------------------+
| + SetMediator(mediator: Mediator): void |
| + Send(event: string): void |
+-------------------------------------------+
^ ^
| |
+-------------------------------+ +-------------------------------+
| ColleagueA | | ColleagueB |
+-------------------------------+ +-------------------------------+
| + Send(event: string): void | | + Send(event: string): void |
+-------------------------------+ +-------------------------------+
3 示例代码
假设我们要实现一个聊天室系统,其中用户可以通过聊天室中介者互相发送消息。
中介者接口
// 中介者接口
public interface IChatMediator
{
void SendMessage(string message, User user);
void RegisterUser(User user);
}
具体中介者
// 具体中介者
public class ChatMediator : IChatMediator
{
private readonly List<User> _users = new List<User>();
public void RegisterUser(User user)
{
_users.Add(user);
}
public void SendMessage(string message, User sender)
{
foreach (var user in _users)
{
// 不要发给自己
if (user != sender)
{
user.Receive(message);
}
}
}
}
同事类
// 同事类
public abstract class User
{
protected IChatMediator _mediator;
protected string _name;
public User(IChatMediator mediator, string name)
{
_mediator = mediator;
_name = name;
}
public abstract void Send(string message);
public abstract void Receive(string message);
}
// 具体同事类
public class ConcreteUser : User
{
public ConcreteUser(IChatMediator mediator, string name) : base(mediator, name)
{
}
public override void Send(string message)
{
Console.WriteLine($"{_name} sends: {message}");
_mediator.SendMessage(message, this);
}
public override void Receive(string message)
{
Console.WriteLine($"{_name} receives: {message}");
}
}
客户端代码
class Program
{
static void Main(string[] args)
{
IChatMediator chatMediator = new ChatMediator();
User user1 = new ConcreteUser(chatMediator, "User1");
User user2 = new ConcreteUser(chatMediator, "User2");
User user3 = new ConcreteUser(chatMediator, "User3");
chatMediator.RegisterUser(user1);
chatMediator.RegisterUser(user2);
chatMediator.RegisterUser(user3);
user1.Send("Hello, everyone!");
}
}
运行结果
User1 sends: Hello, everyone!
User2 receives: Hello, everyone!
User3 receives: Hello, everyone!
在这个例子中,ChatMediator
是中介者,负责协调 User
对象之间的通信。用户通过调用中介者的 SendMessage
方法来发送消息,中介者会将消息转发给其他用户。
6 特点
-
优点:
-
降低耦合度: 中介者模式减少了对象之间的直接依赖,各个对象不需要知道其他对象的存在,只需要与中介者交互。
-
增强可维护性: 对象之间的交互逻辑集中在中介者中,使得修改交互逻辑变得更加容易,而无需修改各个对象。
-
易于扩展: 可以通过增加新的中介者或同事类来扩展系统,而不会影响现有代码。
-
-
缺点:
-
中介者复杂性: 随着系统的复杂度增加,中介者可能变得庞大且复杂,难以维护。
-
可能引入单点故障: 中介者作为通信的中心,如果中介者失败,整个系统的通信可能会中断。
-
7 适用场景
- 复杂的对象交互: 当对象之间存在复杂的交互逻辑且相互依赖时,中介者模式可以简化这些交互。
- 系统易于扩展: 当需要在系统中添加新的交互对象而不希望影响现有代码时,中介者模式非常合适。
- 分离系统的职责: 中介者模式可以帮助将不同对象的职责清晰地分离开来,从而减少耦合。
8 总结
中介者模式通过引入中介者对象来协调多个对象之间的交互,减少了对象之间的耦合度,并使系统更具可维护性和可扩展性。尽管中介者模式能够简化对象的交互逻辑,但需要注意中介者对象的复杂性管理,以避免其变得过于庞大。