初学者,自用笔记
用于把 多个对象(同事对象 Colleague) 之间网状的相互引用与通信集中到一个 中介者(Mediator) 上协调处理,让同事对象不再彼此直接依赖,而是只和中介者交互
- Mediator(中介者接口/抽象类):定义同事对象之间通信/协调的入口(如 Notify(sender, event))。
- ConcreteMediator(具体中介者):实现协调逻辑:谁触发了什么事件后应该通知谁、如何更新状态。
- Colleague(同事对象):各个参与交互的组件/模块(UI面板、系统模块、实体组件),它们只持有 Mediator 引用,不直接互相引用。
简单例子
Mediator
// 中介者接口(定义“同事之间如何通信”的入口)
public interface IChatRoomMediator
{
void Register(User user);
void Send(User from, string message, string toUserName = null); // toUserName==null 表示群发
}
ConcreteMediator
// 具体中介者(集中管理:用户列表、路由规则、群发/私聊)
public sealed class ChatRoom : IChatRoomMediator
{
private readonly Dictionary<string, User> _users = new();
public void Register(User user)
{
if (user == null) throw new ArgumentNullException(nameof(user));
if (string.IsNullOrWhiteSpace(user.Name)) throw new ArgumentException("User must have a name.");
_users[user.Name] = user; // 覆盖同名用户(简单处理)
user.SetMediator(this); // 让同事对象只依赖中介者
}
public void Send(User from, string message, string toUserName = null)
{
if (from == null) throw new ArgumentNullException(nameof(from));
// 1.私聊:中介者负责路由到目标用户
if (!string.IsNullOrEmpty(toUserName))
{
if (_users.TryGetValue(toUserName, out var target))
{
target.Receive($"(DM) {from.Name}: {message}");
}
else
{
from.Receive($"[System] User '{toUserName}' not found.");
}
return;
}
// 2.群发:中介者负责广播(并决定是否给自己也发)
foreach (var kv in _users)
{
var u = kv.Value;
if (u == from) continue; // 简单规则:不回显给自己
u.Receive($"{from.Name}: {message}");
}
}
}
Colleague
// 同事对象(用户)
// 特点:用户不直接持有其他用户引用,只通过 mediator 发消息
public sealed class User
{
public string Name { get; }
private IChatRoomMediator _mediator;
public User(string name)
{
Name = name;
}
public void SetMediator(IChatRoomMediator mediator)
{
_mediator = mediator;
}
public void Say(string message)
{
_mediator.Send(this, message); // 群发
}
public void Whisper(string toUserName, string message)
{
_mediator.Send(this, message, toUserName); // 私聊
}
public void Receive(string message)
{
Console.WriteLine("");
}
}

京公网安备 11010502036488号