1. 介绍

中介模式定义了一个单独的(中介)对象,来封装一组对象之间的交互。将这组对象之间的交互委派给与中介对象交互,来避免对象之间的直接交互。

中介模式的设计思想跟中间层很像,通过引入中介这个中间层,将一组对象之间的交互关系(或者依赖关系)从多对多(网状关系)转换为一对多(星状关系)。原来一个对象要跟 n 个对象交互,现在只需要跟一个中介对象交互,从而最小化对象之间的交互关系,降低了代码的复杂度,提高了代码的可读性和可维护性。

观察者模式和中介模式都是为了实现参与者之间的解耦,简化交互关系。两者的不同在于应用场景上。在观察者模式的应用场景中,参与者之间的交互比较有条理,一般都是单向的,一个参与者只有一个身份,要么是观察者,要么是被观察者。而在中介模式的应用场景中,参与者之间的交互关系错综复杂,既可以是消息的发送者、也可以同时是消息的接收者。

2. 核心思想

  • 解耦直接交互​:将对象间的网状交互关系改为星型结构

  • 集中控制​:所有交互逻辑集中在中介者中

  • 简化对象职责​:对象只需与中介者通信,无需了解其他对象

3. 结构组成

  1. Mediator(中介者接口)​​:定义同事对象到中介者的接口

  2. ConcreteMediator(具体中介者)​​:协调各同事对象的交互

  3. Colleague(同事类)​​:知道其中介者对象,与其他同事通信时通过中介者

4. 游戏开发中典型应用

  1. 聊天系统(如上文示例)

  2. 游戏事件系统

  3. UI管理系统

  4. 多人游戏中的网络消息转发

  5. 游戏对象间的交互协调

5. 代码示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace DesignPatternsPractice.Src.Behavioral.MediatorDesignPattern
{
    /// <summary>
    /// 中介者模式
    ///  实现一个玩家的聊天系统
    /// </summary>
    public class MediatorDesignPattern
    {
        static void Main()
        {
            Mediator mediator = new Mediator();

            // 创建玩家并加入聊天室
            Player player1 = new Player(mediator, "001");
            Player player2 = new Player(mediator, "002");
            Player player3 = new Player(mediator, "003");
            mediator.AddPlayer(player1);
            mediator.AddPlayer(player2);
            mediator.AddPlayer(player3);

            player1.sendMessage("大家好");
            
            
        }
    }
    /// <summary>
    /// 抽象中介者
    /// </summary>
    public interface IMediator
    {
        void sendMessage(string message,Player player);
        void AddPlayer(Player player);
    }
    /// <summary>
    /// 具体中介者
    /// </summary>
    public class Mediator : IMediator
    {

        private List<Player> _players = new List<Player>();

        public void AddPlayer(Player player)
        {
            _players.Add(player);
        }

        public void sendMessage(string message,Player player)
        {
            foreach (var item in _players)
            {
                // 防止发给自己 
                if (player != item)
                    item.AcceptMessage(message);
            }
        }
    }

    public abstract class IPlayer
    {
        public Mediator _mediator;
        public string _Name { get; }

        public IPlayer(Mediator mediator, string name)
        {
            _mediator = mediator;
            _Name = name;
        }
        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="message"></param>
        public abstract void AcceptMessage(string message);
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="message"></param>
        public abstract void sendMessage(string message);
    }

    public class Player : IPlayer
    {
        public Player(Mediator mediator, string name) : base(mediator, name)
        {
        }

        public override void AcceptMessage(string message)
        {
            Console.WriteLine($"{_Name}:收到了消息-->{message}");
        }

        public override void sendMessage(string message)
        {
            _mediator.sendMessage(message, this);
        }
    }
}

6. 与观察者模式的区别

特性

中介者模式

观察者模式

​交互方向​

双向(同事与中介者相互知晓)

单向(主题→观察者,观察者不知晓主题)

​控制中心化程度​

高度集中(中介者掌握全部交互逻辑)

分散(观察者各自处理通知)

​对象关系​

多对多关系通过中介者变为星型结构

一对多关系

​使用场景​

对象间有复杂交互需要协调

状态变化需要广播通知多个对象

​耦合度​

同事类与中介者耦合

主题与观察者松耦合

​典型应用​

聊天系统、游戏对象交互协调

成就系统、UI更新、事件通知