开发者

C#和Unity中的中介者模式使用方式

目录
  • C#中的中介者模式详解
    • 一、中介者模式的基本概念
      • 1. 定义
      • 2. 组成要素
      • 3. 模式结构
    • 二、中介者模式的特点
      • 1. 优点
      • 2. 缺点
    • 三、中介者模式的实现方式
      • 1. 基本实现
      • 2. 使用示例
      • 3. 更复杂的实现(聊天室示例)
    • 四、中介者模式的使用场景
      • 1. 典型使用场景
      • 2. 实际应用示例
    • 五、中介者模式与其他模式的关系
      • 六、最佳实践
        • 七、总结
          • 八、使用事件或委托简化实现中介者模式
            • 1. 基于事件的简化实现
            • 2. 使用Action委托的简化实现
            • 3. 使用.NET内置EventBus的简化实现
            • 4. 比较与选择
            • 5. 最佳实践建议
          • 八、在Unity中的应用
            • 示例1:UI系统管理
            • 示例2:游戏事件系统
            • 示例3:AI协调系统
            • 在Unity中的实现建议
        • 总结

          C#中的中介者模式详解

          中介者模式(Mediator Pattern)是一种行为设计模式,它能减少对象之间混乱无序的依赖关系,通过引入一个中介者对象来封装一系列对象之间的交互。

          一、中介者模式的基本概念

          1. 定义

          中介者模式定义了一个对象来封装一组对象之间的交互方式,使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

          2. 组成要素

          • Mediator(中介者接口) :定义各个同事对象通信的接口
          • ConcreteMediator(具体中介者) :实现中介者接口,协调各同事对象的交互
          • Colleague(同事类) :每个同事对象都知道它的中介者对象,与其他同事通信时都通过中介者

          3. 模式结构

          [同事A] ────> [中介者] <─── [同事B]
              ↑____________|____________↑
          

          二、中介者模式的特点

          1. 优点

          • 降低耦合度:将对象之间的网状结构变为星型结构
          • 集中控制:将交互复杂性集中到中介者中
          • 简化对象协议:用一对多的交互代替多对多的交互
          • 易于扩展:新增同事类只需修改中介者或新增具体中介者

          2. 缺点

          • 中介者可能变得复杂:如果同事类过多,中介者会变得庞大复杂
          • 过度集中化:中介者集中了太多控制逻辑,可能成为"上帝对象"

          三、中介者模式的实现方式

          1. 基本实现

          // 中介者接口
          public interface IMediator
          {
              void Notify(object sender, string ev);
          }
          
          // 基础同事类
          public abstract class Colleague
          {
              protected IMediator _mediator;
          
              public Colleague(IMediator mediator)
              {
                  _mediator = mediator;
              }
          }
          
          // 具体同事A
          public class ConcreteColleagueA : Colleague
          {
              public ConcreteColleagueA(IMediator mediator) : base(mediator) { }
          
              public void DoA()
              {
                  Console.WriteLine("ColleagueA does A.");
                  _mediator.Notify(this, "A");
              }
          
              public void DoB()
              {
                  Console.WriteLine("ColleagueA does B.");
              }
          }
          
          // 具体同事B
          public class ConcreteColleagueB : Colleague
          {
              public ConcreteColleagueB(IMediator mediator) : base(mediator) { }
          
              public void DoC()
              {
                  Console.WriteLine("ColleagueB does C.");
                  _mediator.Notify(this, "C");
              }
          
              public void DoD()
              {
                  Console.WriteLine("ColleagueB does D.");
              }
          }
          
          // 具体中介者
          public class ConcreteMediator : IMediator
          {
              private ConcreteColleagueA _colleagueA;
              private ConcreteColleagueB _colleagueB;
          
              public ConcreteColleagueA ColleagueA
              {
                  set { _colleagueA = value; }
              }
          
              public ConcreteColleagueB ColleagueB
              {
                  set { _colleagueB = value; }
              }
          
              public void Notify(object sender, string ev)
              {
                  if (ev == "A")
                  {
                      Console.WriteLine("Mediator reacts on A and triggers:");
                      _colleagueB.DoC();
                  }
            
                  if (ev == "C")
                  {
                      Console.WriteLine("Mediator reacts on C and triggers:");
                      _colleagueA.DoB();
                      _colleagueB.DoD();
                  }
              }
          }
          

          2. 使用示例

          // 客户端代码
          var mediator = new ConcreteMediator();
          var colleagueA = new ConcreteColleagueA(mediator);
          var colleagueB = new ConcreteColleagueB(mediator);
          
          mediator.ColleagueA = colleagueA;
          mediator.ColleagueB = colleagueB;
          
          Console.WriteLine("Client triggers operation A.");
          colleagueA.DoA();
          
          Console.WriteLine();
          
          Console.WriteLine("Client triggers operation C.");
          colleagueB.DoC();
          

          3. 更复杂的实现(聊天室示例)

          // 中介者接口
          public interface IChatRoom
          {
              void Register(Participant participant);
              void Send(string from, string to, string message);
          }
          
          // 具体中介者 - 聊天室
          public class ChatRoom : IChatRoom
          {
              private Dictionary<string, Participant> _participants = new Dictionary<string, Participant>();
          
              public void Register(Participant participant)
              {
                  if (!_participants.ContainsKey(participant.Name))
                  {
                      _participants.Add(participant.Name, participant);
                  }
                  participant.ChatRoom = this;
              }
          
              public void Send(string from, string to, string message)
              {
                  if (_participants.TryGetValue(to, out var participant))
                  {
                      participant.Receive(from, message);
                  }
              }
          }
          
          // 同事基类
          public abstract class Participant
          {
              public string Name { get; }
              public IChatRoom ChatRoom { get; set; }
          
              protected Participant(string name)
              {
                  Name = name;
              }
          
              public void Send(string to, string message)
              {
                  ChatRoom.Send(Name, to, message);
              }
          
              public abstract void Receive(string from, string message);
          }
          
          // 具体同事类
          public class User : Participant
          {
              public User(string name) : base(name) { }
          
              public override void Receive(string from, string message)
              {
                  Console.WriteLine($"{from} to {Name}: '{message}'");
              }
          }
          
          // 使用
          var chatRoom = new ChatRoom();
          
          var john = new User("John");
          var jane = new User("Jane");
          
          chatRoom.Register(john);
          chatRoom.Register(jane);
          
          john.Send("Jane", "Hi Jane!");
          jane.Send("John", "Hello John!");
          

          四、中介者模式的使用场景

          1. 典型使用场景

          1. 对象间存在复杂的引用关系:当系统中对象之间存在复杂的网状引用关系,导致系统结构混乱且难以理解时。
          2. 需要集中控制对象间的交互:当多个类之间有复杂的交互逻辑,且这些逻辑需要集中管理时。
          3. 想定制分布在多个类中的行为:当行为分布在多个类中,但又需要根据需求改变这些行为时。
          4. GUI组件交互:图形用户界面中,各种控件(按钮、文本框等)之间的交互。
          5. 消息传递系统:如聊天应用、通知系统等需要多方通信的场景。

          2. 实际应用示例

          示例1:航空管制系统

          // 航空交通管制中介者接口
          public interface IAirTrafficControl
          {
              // 注册飞机到管制系统
              void RegisterAircraft(Aircraft aircraft);
            
              // 发送警告消息(发送者飞机 + 消息内容)
              void SendwarningMessage(Aircraft sender, string message);
          }
          
          // 飞机类(同事类)
          public class Aircraft
          {
              // 飞机呼号(唯一标识)
              public string CallSign { get; }
            
              // 持有对航空管制中心(中介者)的引用
              private IAirTrafficControl _atc;
            
              // 构造函数:初始化飞机并注册到管制系统
              public Aircraft(string callSign, IAirTrafficControl atc)
              {
                  CallSign = callSign;
                  _atc = atc;
                  _atc.RegisterAircraft(this); // 自动注册到管制系统
              }
            
              // 发送警告消息(通过管制中心转发)
              public void SendWarning(string message)
              {
                  // 不直接联系其他飞机,而是通过管制中心发送
                  _atc.SendWarningMessage(this, message);
              }
            
              // 接收来自其他飞机的警告
              public void ReceiveWarning(string from, string message)
              {
                  // 打印接收到的警告信息
                  Console.WriteLine($"{CallSign} received from {from}: {message}");
              }
          }
          
          // 塔台管制中心(具体中介者实现)
          public class Tower : IAirTrafficControl
          {
              // 保存所有注册的飞机列表
              private List<Aircraft> _aircrafts = new List<Aircraft>();
            
              // 注册飞机到管制系统
              public void RegisterAircraft(Aircraft aircraft)
              {
                  // 防止重复注册
                  if (!_aircrafts.Contains(aircraft))
                  {
                      _aircrafts.Add(aircraft);
                  }
              }
            
              // 处理警告消息转发
              public void SendWarningMessage(Aircraft sender, string message)
              {
                  // 遍历所有已注册的飞机(排除发送者自己)
                  foreach (var aircraft in _aircrafts.Where(a => a != sender))
                  {
                      // 将消息转发给其他飞机
                      aircraft.ReceiveWarning(sender.CallSign, message);
                  }
              }
          }
          

          示例2:订单处理系统

          // 订单中介者接口
          public interface IOrderMediator
          {
              // 通知方法:组件通过此方法与中介者通信
              // sender - 触发事件的组件
              // eventType - 事件类型标识
              void Notify(OrderComponent sender, string eventType);
          }
          
          // 订单组件基类(抽象同事类)
          public abstract class OrderComponent
          {
              // 持有对中介者的引用
              protected IOrderMediator _mediator;
            
              // 构造函数:注入中介者实例
              public OrderComponent(IOrderMediator mediator)
              {
                  _mediator = mediator;
              }
          }
          
          // 库存系统(具体同事类)
          public class InventorySystem : OrderComponent
          {
              // 构造函数:调用基类构造函数
              public InventorySystem(IOrderMediator mediator) : base(mediator) { }
            
              // 检查库存方法
              public void CheckStock()
              {
                  Console.WriteLine("Checking stock...");
                  // 通知中介者库存已检查
                  _mediator.Notify(this, "StockChecked");
              }
            
              // 更新库存方法
              public void UpdateStock()
              {
                  Console.WriteLine("Updating stock...");
              }
          }
          
          // 支付系统(具体同事类)
          public class PaymentSystem : OrderComponent
          {
              // 构造函数:调用基类构造函数
              public PaymentSystem(IOrderMediator mediator) : base(mediator) { }
            
              // 处理支付方法
              public void ProcessPayment()
              {
                  Console.WriteLine("Processing payment...");
                  // 通知中介者支付已处理
                  _mediator.Notify(this, "PaymentProcessed");
              }
          }
          
          // 订单中介者实现(具体中介者)
          public class OrderMediator : IOrderMediator
          {
              // 持有库存系统引用
              private InventorySystem _inventory;
              // 持有支付系统引用
              private PaymentSystem _payment;
            
              // 构造函数:注入需要的组件
              public OrderMediator(InventorySystem inventory, PaymentSystem payment)
              {
                  _inventory = inventory;
                  _payment = payment;
              }
            
              // 实现通知处理方法
              public void Notify(OrderComponent sender, string eventType)
              {
                  // 如果是库存系统且事件类型为"StockChecked"
                  if (sender is InventorySystem && eventType == "StockChecked")
                  {
                      // 触发支付系统处理支付
                      _payment.ProcessPayment();
                  }
                  // 如果是支付系统且事件类型为"PaymentProcessed"
                  else if (sender is PaymentSystem && eventType == "PaymentProcessed")
                  {
                      // 更新库存
                      _inventory.UpdateStock();
                      Console.WriteLine("Order completed!");
                  }
              }
          }
          

          五、中介者模式与其他模式的关系

          与外观模式的区别

          • 外观模式为子系统提供简化接口,但不添加新功能
          • 中介者模式集中同事对象间的通信,可以添加协调逻辑

          与观察者模式的区别

          • 观察者模式通过订阅/发布机制实现单向通信
          • 中介者模式对象间通过中介者进行双向通信

          与命令模式结合

          • 可以使用命令模式将请求封装为对象,由中介者管理这些命令

          六、最佳实践

          合理划分责任

          • 中介者应只负责协调,不承担业务逻辑
          • 避免创建"上帝对象"

          考虑使用事件

          • 在C#中可以使用事件机制实现轻量级中介者

          适度使用

          • 只在对象间交互确实复杂时使用
          • 简单交互直接引用可能更合适

          可测试性设计

          • 使中介者易于替换,方便单元测试

          性能考虑

          • 高频交互场景需评估中介者带来的性能影响

          七、总结

          中介者模式是管理复杂对象交互的强大工具,特别适用于以下场景:

          • 对象间存在大量直接连接
          • 系统组件难以复用
          • 交互逻辑分散难以理解
          • 需要集中控制对象间通信

          在C#中实现中介者模式时,可以:

          1. 定义清晰的中介者接口
          2. 使同事类只依赖于中介者
          3. 将复杂的交互逻辑封装在中介者中
          4. 考虑使用事件或委托简化实现

          正确使用中介者模式可以显著降低系统复杂度,提高代码的可维护性和灵活性。

          八、使用事件或委托简化实现中介者模式

          中介者模式可以通过C#的事件和委托机制来简化实现,这种方式可以减少中介者类的复杂性,同时保持对象间的解耦。下面我将展示如何使用事件来重构中介者模式。

          1. 基于事件的简化实现

          基本架构

          // 定义事件参数基类
          public abstract class OrderEventArgs : EventArgs
          {
              public string EventType { get; set; }
          }
          
          // 库存系统事件参数
          public class InventoryEventArgs : OrderEventArgs
          {
              public int ProductId { get; set; }
              public int Quantity { get; set; }
          }
          
          // 支付系统事件参数
          public class PaymentEventArgs : OrderEventArgs
          {
              public decimal Amount { get; set; }
              public string PaymentMethod { get; set; }
          }
          
          // 订单组件基类(使用事件)
          public abstract class OrderComponent
          {
              // 定义事件处理器委托
              public delegate void OrderEventHandler(object sender, OrderEventArgs e);
            
              // 组件事件
              public event OrderEventHandler OnOrderEvent;
            
              // 触发事件的方法
              protected void RaiseEvent(OrderEventArgs e)
              {
                  OnOrderEvent?.Invoke(this, e);
              }
          }
          
          // 库存系统实现
          public class InventorySystem : OrderComponent
          {
              public void CheckStock(int productId)
              {
                  Console.WriteLine($"Checking stock for product {productId}...");
                  RaiseEvent(new InventoryEventArgs {
                      EventType = "StockChecked",
                      ProductId = productId,
                      Quantity = 100 // 假设检查到有100个库存
                  });
              }
            
              public void UpdateStock(int productId, int quantity)
              {
                  Console.WriteLine($"Updating stock for product {productId}, quantity: {quantity}");
              }
          }
          
          // 支付系统实现
          public class PaymentSystem : OrderComponent
          {
              public void ProcessPayment(decimal amount, string method)
              {
                  Console.WriteLine($"Processing payment of {amount} via {method}");
                  RaiseEvent(new PaymentEventArgs {
                      EventType = "PaymentProcessed",
                      Amount = amount,
                      PaymentMethod = method
                  });
              }
          }
          

          事件协调器(轻量级中介者)

          public class OrderEventCoordinator
          {
              private readonly InventorySystem _inventory;
              private readonly PaymentSystem _payment;
            
              public OrderEventCoordinator(InventorySystem inventory, PaymentSystem payment)
              {
                  _inventory = inventory;
                  _payment = payment;
            
                  // 订阅库存系统事件
                  _inventory.OnOrderEvent += HandleInventoryEvent;
            
                  // 订阅支付系统事件
                  _payment.OnOrderEvent += HandlePaymentEvent;
              }
            
              private void HandleInventoryEvent(object sender, OrderEventArgs e)
              {
                  if (e is InventoryEventArgs args && args.EventType == "StockChecked")
                  {
                      // 库存检查完成后处理支付
                      _payment.ProcessPayment(99.99m, "CreditCard");
                  }
              }
            
              private void HandlePaymentEvent(object sender, OrderEventArgs e)
              {
                  if (e is PaymentEventArgs args && args.EventType == "PaymentProcessed")
                  {
                      // 支付完成后更新库存
                      _inventory.UpdateStock(1, -1); // 假设产品ID为1,减少1个库存
                      Console.WriteLine("Order completed!");
                  }
              }
          }
          

          2. 使用Action委托的简化实现

          更轻量的实现方式

          // 组件基类(使用Action委托)
          public abstract class OrderComponent
          {
              protected Action<string, object> MediatorCallback { get; }
            
              public OrderComponent(Action<string, object> mediatorCallback)
              {
                  MediatorCallback = mediatorCallback;
              }
          }
          
          // 库存系统
          public class InventorySystem : OrderComponent
          {
              public InventorySystem(Action<string, object> callback) : base(callback) {}
            
              public void CheckStock(int productId)
              {
                  Console.WriteLine($"Checking stock for product {productId}...");
                  MediatorCallback?.Invoke("StockChecked", new { ProductId = productId });
              }
            
              public void UpdateStock(int productId, int quantity)
              {
                  Console.WriteLine($"Updating stock for product {productId}, quantity: {quantity}");
              }
          }
          
          // 支付系统
          public class PaymentSystem : OrderComponent
          {
              public PaymentSystem(Action<string, object> callback) : base(callback) {}
            
              public void ProcessPayment(decimal amount, string method)
              {
                  Console.WriteLine($"Processing payment of {amount} via {method}");
                  MediatorCallback?.Invoke("PaymentProcessed", new { Amount = amount, Method = method });
              }
          }
          
          // 使用Lambda表达式作为中介者
          public class Program
          {
              public static void Main()
              {
                  // 创建支付系统并定义其回调
                  var payment = new PaymentSystem((evenjavascripttType, data) => 
                  {
                      if (eventType == "PaymentProcessed")
                      {
                          Console.WriteLine("Payment processed callback");
                      }
                  });
            
                  // 创建库存系统并定义完整流程
                  var inventory = new InventorySystem((eventType, data) => 
                  {
                      dynamic eventData = data;
                
                      if (eventType == "StockChecked")
                      {
                          Console.WriteLine($"Stock checked for product {eventData.ProductId}");
                          payment.ProcessPayment(99.99m, "CreditCard");
                      }
                      else if (eventType == "PaymentProcessed")
                      {
                          inventory.UpdateStock(1, -1);
                          Console.WriteLine("Order completed!");
                      }
                  });
            
                  // 启动流程
                  inventory.CheckStock(1);
              }
          }
          

          3. 使用.NET内置EventBus的简化实现

          基于MediatR库的实现

          // 安装MediatR NuGet包
          // Install-Package MediatR
          
          // 定义事件/通知
          public class StockCheckedEvent : INotification
          {
              public int ProductId { get; set; }
          }
          
          public class PaymentProcessedEvent : INotification
          {
              public decimal Amount { get; set; }
          }
          
          // 定义处理器
          public class StockCheckedHandler : INotificationHandler<StockCheckedEvent>
          {
              private readonly IMediator _mediator;
            
              public StockCheckedHandler(IMediator mediator)
              {
                  _mediator = mediator;
              }
            
              public async Task Handle(StockCheckedEvent notification, CancellationToken ct)
              {
                  Console.WriteLine($"Stock checked for product {notification.ProductId}");
                  await _mediator.Publish(new PaymentProcessedEvent { Amount = 99.99m }, ct);
              }
          }
          
          public class PaymentProcessedHandler : INotificationHandler<PaymentProcessedEvent>
          {
              public Task Handle(PaymentProcessedEvent notification, CancellationToken ct)
              {
                  Console.WriteLine($"Payment processed: {notification.Amount}");
                  Console.WriteLine("Order completed!");
                  return Task.CompletedTask;
              }
          }
          
          // 使用示例
          var services = new ServiceCollection();
          services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
          var provider = services.BuildServiceProvider();
          
          var mediator = provider.GetRequiredService<IMediator>();
          await mediator.Publish(new StockCheckedEvent { ProductId = 1 });
          

          4. 比较与选择

          实现方式优点缺点适用场景
          经典中介者模式结构清晰,职责明确中介者类可能变得庞大复杂交互,需要集中控制
          基于事件实现松耦合,易于扩展事件处理逻辑分散组件间交互简单,需要灵活扩展
          Action委托回调实现简单,轻量级不适合复杂交互简单流程,快速实现
          MediatR事件总线专业解耦,支持异步需要引入第三方库企业级应用,需要强大事件处理

          5. 最佳实践建议

          1. 简单场景:使用Action委托或简单事件实现
          2. 中等复杂度:使用基于事件的协调器模式
          3. 企业级应用:考虑使用MediatR等事件总线库
          4. 保持一致性:项目中统一使用一种实现方式
          5. 适度抽象:不要过度设计,根据实际需求选择

          八、在Unity中的应用

          示例1:UI系统管理

          using UnityEngine;
          using UnityEngine.UI;
          
          // 中介者接口
          public interface IUIMediator
          {
              void Notify(UIComponent sender, string eventName);
          }
          
          // 具体中介者 - UI管理器
          public class UIManager : MonoBehaviour, IUIMediator
          {
              public Button startButton;
              public Button optionsButton;
              public Button quitButton;
              public GameObject mainMenuPanel;
              public GameObject optionsPanel;
            
              private void Start()
              {
                  // 为每个UI组件设置中介者引用
                  startButton.GetComponent<UIComponent>().SetMediator(this);
                  optionsButton.GetComponent<UIComponent>().SetMediator(this);
                  quitButton.GetComponent<UIComponent>().SetMediator(this);
            
                  // 初始化UI状态
                  mainMenuPanel.SetActive(true);
                  optionsPanel.SetActive(false);
              }
            
              // 处理UI组件通知
              public void Notify(UIComponent sender, string eventName)
              {
                  switch (eventName)
                  {
                      case "StartButtonClicked":
                          OnStartGame();
                          break;
                      case "OptionsButtonClicked":
                          OnOpenOptions();
                          break;
                      case "QuitButtonClicked":
                          OnQuitGame();
                          break;
                      case "BackButtonClicked":
                          OnBackToMenu();
                          break;
                  }
              }
            
              private void OnStartGame()
              {
                  Debug.Log("开始游戏");
                  mainMenuPanel.SetActive(false);
                  // 这里可以添加游戏开始的逻辑
              }
            
              private void OnOpenOptions()
              {
                  Debug.Log("打开选项菜单");
                  mainMenuPanel.SetActive(false);
                  optionsPanel.SetActive(true);
              }
            
              private void OnQuitGame()
              {
                  Debug.Log("退出游戏");
                  Application.Quit();
              }
            
              private void OnBackToMenu()
              {
                  Debug.Log("返回主菜单");
                  optionsPanel.SetActive(false);
                  mainMenuPanel.SetActive(true);
              }
          }
          
          // 同事类 - UI组件基类
          public class UIComponent : MonoBehaviour
          {
              protected IUIMediator mediator;
            
              // 设置中介者
              public void SetMediator(IUIMediator mediator)
              {
                  this.mediator = mediator;
              }
            
              // 通知中介者
              protected void NotifyMediator(string eventName)
              {
                  mediator?.Notify(this, eventName);
              }
          }
          
          // 具体同事类 - 开始按钮
          public class StartButton : UIComponent
          {
              private Button button;
            
              private void Awake()
              {
                  button = GetComponent<Button>();
                  button.onClick.AddListener(OnClick);
              }
            
              private void OnClick()
              {
                  NotifyMediator("StartButtonClicked");
              }
          }
          
          // 具体同事类 - 选项按钮
          public class OptionsButton : UIComponent
          {
              private Button button;
            
              private void Awake()
              {
                  button = GetComponent<Button>();
                  button.onClick.AddListener(OnClick);
              }
            
              private void OnClick()
              {
                  NotifyMediator("OptionsButtonClicked");
              }
          }
          
          // 具体同事类 - 退出按钮
          public class QuitButton : UIComponent
          {
              private Button button;
            
              private void Awake()
              {
                  button = GetComponent<Button>();
                  button.onClick.AddListener(OnClick);
              }
            
              private void OnClick()
              {
                  NotifyMediator("QuitButtonClicked");
              }
          }
          
          // 具体同事类 - 返回按钮
          public class BackButton : UIComponent
          {
              private Button button;
            
              private void Awake()
              {
                  button = GetComponent<Button>();
                  button.onClick.AddListener(OnClick);
              }
            
              private void OnClick()
              {
                  NotifyMediator("BackButtonClicked");
              }
          }
          

          示例2:游戏事件系统

          using UnityEngine;
          using System.Collections.Generic;
          
          // 事件类型枚举
          public enum GameEventType
          {
              PlayerDied,
              EnemyKilled,
              ItemCollected,
              LevelCompleted
          }
          
          // 中介者接口
          public interface IGameEventMediator
          {
              void Subscribe(GameEventType eventType, IGameEventSubscriber subscriber);
              void Unsubscribe(GameEventType eventType, IGameEventSubscriber subscriber);
              void Publish(GameEventType eventType, object sender, object eventData);
          }
          
          // 具体中介者 - 游戏事件管理器
          public class GameEventManager : MonoBehaviour, IGameEventMediator
          {
              private Dictionary<GameEventType, List<IGameEventSubscriber>> subscribers = 
                  new Dictionary<GameEventType, List<IGameEventSubscriber>>();
            
              // 订阅事件
              public void Subscribe(GameEventType eventType, IGameEventSubscriber subscriber)
              {
                  if (!subscribers.ContainsKey(eventType))
                  {
                      subscribers[eventType] = new List<IGameEventSubscriber>();
                  }
            
                  if (!subscribers[eventType].Contains(subscriber))
                  {
                      subscribers[eventType].Add(subscriber);
                  }
              }
            
              // 取消订阅
              public void Unsubscribe(GameEventType eventType, IGameEventSubscriber subscriber)
              {
                  if (subscribers.ContainsKey(eventType))
                  {
                      subscribers[eventType].Remove(subscriber);
                  }
              }
            
              // 发布事件
              public void Publish(GameEventType eventType, object sender, object eventData)
              {
                  if (subscribers.ContainsKey(eventType))
                  {
                      foreach (var subscriber in subscribers[eventType])
                      {
                          subscriber.OnEvent(eventType, sender, eventData);
                      }
                  }
              }
          }
          
          // 同事接口 - 事件订阅者
          public interface IGameEventSubscriber
          {
              void OnEvent(GameEventType eventType, object sender, object eventData);
          }
          
          // 具体同事类 - 玩家控制器
          public class PlayerController : MonoBehaviour, IGameEventSubscriber
          {
              private IGameEventMediator eventMediator;
              public int health = 100;
            
              private void Start()
              {
                  eventMediator = FindObjectOfType<GameEventManager>();
                  eventMediator.Subscribe(GameEventType.PlayerDied, this);
              }
            
              private void OnDestroy()
              {
                  eventMediator?.Unsubscribe(GameEventType.PlayerDied, this);
              }
            
              public void TakeDamage(int damage)
              {
                  health -= damage;
            
                  if (health <= 0)
                  {
                      eventMediator.Publish(GameEventType.PlayerDied, this, null);
                  }
              }
            
              public void OnEvent(GameEventType eventType, object sender, object eventData)
              {
                  if (eventType == GameEventType.PlayerDied && sender == this)
                  {
                      Debug.Log("玩家死亡事件处理");
                      // 处理玩家死亡逻辑
                  }
              }
          }
          
          // 具体同事类 - 成就系统
          public class AchievementSystem : MonoBehaviour, IGameEventSubscriber
          {
              private IGameEventMediator eventMediator;
            
              private void Start()
              {
                  eventMediator = FindObjectOfType<GameEventManager>();
                  eventMediator.Subscribe(GameEventType.EnemyKilled, this);
                  eventMediator.Subscribe(GameEventType.ItemCollected, this);
              }
            
              private void OnDestroy()
              {
                  eventMediator?.Unsubscribe(GameEventType.EnemyKilled, this);
                  eventMediator?.Unsubscribe(GameEventType.ItemCollected, this);
              }
            
              public void OnEvent(GameEventType eventType, object sender, object eventData)
              {
                  switch (eventType)
                  {
                      case GameEventType.EnemyKilled:
                          Debug.Log("成就系统: 敌人被击杀");
                          // 更新击杀成就
                          break;
                      case GameEventType.ItemCollected:
                          Debug.Log("成就系统: 物品被收集");
                          // 更新收集成就
                          break;
                  }
              }
          }
          
          // 具体同事类 - 音频管理器
          public class AudioManager : MonoBehaviour, IGameEventSubscriber
          {
              private IGameEventMediator eventMediator;
            
              private void Start()
              {
                  eventMediator = FindObjectOfType<GameEventManager>();
                  eventMediator.Subscribe(GameEventType.PlayerDied, this);
                  eventMediator.Subscribe(GameEventType.LevelCompleted, this);
              }
            
              private void OnDestroy()
              {
                  eventMediator?.Unsubscribe(GameEventType.PlayerDied, this);
                  eventMediator?.Unsubscribe(GameEventType.LevelCompleted, this);
              }
            
              public void OnEvent(GameEventType eventType, object sender, object eventData)
              {
                  switch (eventType)
                  {
                      编程客栈case GameEventType.PlayerDied:
                          Debug.Log("播放死亡音效");
                          // 播放死亡音效
                          break;
                      case GameEventType.LevelCompleted:
                          Debug.Log("播放关卡完成音效");
                          // 播放胜利音效
                          break;
                  }
              }
          }
          

          示例3:AI协调系统

          using UnityEngine;
          using System.Collections.Generic;
          
          // 中介者接口
          public interface IAIMediator
          {
              void RegisterAI(AIEntity ai);
              void UnregisterAI(AIEntity ai);
              void SendMessage(AIEntity sender, string message);
          }
          
          // 具体中介者 - AI协调器
          public class AICoordinator : MonoBehaviour, IAIMediator
          {
              privatejs List<AIEntity> aiEntities = new List<AIEntity>();
            
              // 注册AI实体
              public void RegisterAI(AIEntity ai)
              {
                  if (!aiEntities.Contains(ai))
                  {
                      aiEntities.Add(ai);
                  }
              }
            
              // 注销AI实体
              public void UnregisterAI(AIEntity ai)
              {
                  aiEntities.Remove(ai);
              }
            
              // 广播消息
              public void SendMessage(AIEntity sender, string message)
              {
                  foreach (var ai in aiEntities)
                  {
                      if (ai != sender) // 不发送给自己
                      {
                          ai.ReceiveMessage(message);
                      }
                  }
              }
          }
          
          // 同事类 - AI实体基类
          public abstract class AIEntity : MonoBehaviour
          {
              protected IAIMediator mediator;
            
              // 设置中介者
              public void SetMediator(IAIMediator mediator)
              {
                  this.mediator = mediator;
                  mediator.RegisterAI(this);
              }
            
              // 发送消息
              protected void SendToOthers(string message)
              {
                  mediator?.SendMessage(this, message);
              }
            
              // 接收消息
              public abstract void ReceiveMessage(string message);
            
              private void OnDestroy()
              {
                  mediator?.UnregisterAI(this);
              }
          }
          
          // 具体同事类 - 守卫AI
          public class GuardAI : AIEntity
          {
              private bool isAlerted = false;
            
              private void Start()
              {
                  // 在中介者中注册
                  SetMediator(FindObjectOfType<AICoordinator>());
              }
            
              // 发现玩家
              public void SpotPlayer()
              {
                  Debug.Log("守卫发现玩家!");
                  isAlerted = true;
                  SendToOthers("PlayerSpotted");
              }
            
              // 接收消息
              public override void ReceiveMessage(string message)
              {
                  if (message == "PlayerSpotted" && !isAlerted)
                  {
                      Debug.Log("守卫收到警报: 玩家被发现!");
                      isAlerted = true;
                      // 进入警戒状态
                  }
              }
          }
          
          // 具体同事类 - 巡逻AI
          public class PatrolAI : AIEntity
          {
              private bool isAlerted = false;
            
              prijsvate vophpid Start()
              {
                  // 在中介者中注册
                  SetMediator(FindObjectOfType<AICoordinator>());
              }
            
              // 发现玩家
              public void SpotPlayer()
              {
                  Debug.Log("巡逻AI发现玩家!");
                  isAlerted = true;
                  SendToOthers("PlayerSpotted");
              }
            
              // 接收消息
              public override void ReceiveMessage(string message)
              {
                  if (message == "PlayerSpotted" && !isAlerted)
                  {
                      Debug.Log("巡逻AI收到警报: 玩家被发现!");
                      isAlerted = true;
                      // 改变巡逻路线
                  }
              }
          }
          
          // 具体同事类 - 狙击手AI
          public class SniperAI : AIEntity
          {
              private bool isAlerted = false;
            
              private void Start()
              {
                  // 在中介者中注册
                  SetMediator(FindObjectOfType<AICoordinator>());
              }
            
              // 接收消息
              public override void ReceiveMessage(string message)
              {
                  if (message == "PlayerSpotted" && !isAlerted)
                  {
                      Debug.Log("狙击手收到警报: 玩家被发现!准备狙击...");
                      isAlerted = true;
                      // 进入狙击位置
                  }
              }
          }
          

          在Unity中的实现建议

          1. 使用ScriptableObject:可以将中介者实现为ScriptableObject,便于在编辑器中配置
          2. 与事件系统结合:Unity自身的EventSystem也可以看作是一种中介者模式的实现
          3. 考虑性能:对于高频交互,注意中介者可能成为性能瓶颈
          4. 避免过度使用:不是所有对象交互都需要中介者,简单交互可以直接通信
          5. 分层设计:可以为不同子系统设计不同的中介者,避免单个中介者过于复杂

          总结

          以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

          0

          上一篇:

          下一篇:

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          最新开发

          开发排行榜