初学者,自用笔记

用于把 多个对象(同事对象 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("");
    }
}