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

2025-08-14 10:50

本文主要是介绍C#和Unity中的中介者模式使用方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《C#和Unity中的中介者模式使用方式》中介者模式通过中介者封装对象交互,降低耦合度,集中控制逻辑,适用于复杂系统组件交互场景,C#中可用事件、委托或MediatR实现,提升可维护性与灵活性...

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)
        {
            China编程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. 分层设计:可以为不同子系统设计不同的中介者,避免单个中介者过于复杂

总结

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

这篇关于C#和Unity中的中介者模式使用方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155728

相关文章

SpringBoot中ResponseEntity的使用方法举例详解

《SpringBoot中ResponseEntity的使用方法举例详解》ResponseEntity是Spring的一个用于表示HTTP响应的全功能对象,它可以包含响应的状态码、头信息及响应体内容,下... 目录一、ResponseEntity概述基本特点:二、ResponseEntity的基本用法1. 创

使用Java填充Word模板的操作指南

《使用Java填充Word模板的操作指南》本文介绍了Java填充Word模板的实现方法,包括文本、列表和复选框的填充,首先通过Word域功能设置模板变量,然后使用poi-tl、aspose-words... 目录前言一、设置word模板普通字段列表字段复选框二、代码1. 引入POM2. 模板放入项目3.代码

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

MySQL之搜索引擎使用解读

《MySQL之搜索引擎使用解读》MySQL存储引擎是数据存储和管理的核心组件,不同引擎(如InnoDB、MyISAM)采用不同机制,InnoDB支持事务与行锁,适合高并发场景;MyISAM不支持事务,... 目录mysql的存储引擎是什么MySQL存储引擎的功能MySQL的存储引擎的分类查看存储引擎1.命令

Python sys模块的使用及说明

《Pythonsys模块的使用及说明》Pythonsys模块是核心工具,用于解释器交互与运行时控制,涵盖命令行参数处理、路径修改、强制退出、I/O重定向、系统信息获取等功能,适用于脚本开发与调试,需... 目录python sys 模块详解常用功能与代码示例获取命令行参数修改模块搜索路径强制退出程序标准输入

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

5 种使用Python自动化处理PDF的实用方法介绍

《5种使用Python自动化处理PDF的实用方法介绍》自动化处理PDF文件已成为减少重复工作、提升工作效率的重要手段,本文将介绍五种实用方法,从内置工具到专业库,帮助你在Python中实现PDF任务... 目录使用内置库(os、subprocess)调用外部工具使用 PyPDF2 进行基本 PDF 操作使用

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的

nodejs打包作为公共包使用的完整流程

《nodejs打包作为公共包使用的完整流程》在Node.js项目中,打包和部署是发布应用的关键步骤,:本文主要介绍nodejs打包作为公共包使用的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言一、前置准备二、创建与编码三、一键构建四、本地“白嫖”测试(可选)五、发布公共包六、常见踩坑提醒