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

相关文章

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Python使用python-pptx自动化操作和生成PPT

《Python使用python-pptx自动化操作和生成PPT》这篇文章主要为大家详细介绍了如何使用python-pptx库实现PPT自动化,并提供实用的代码示例和应用场景,感兴趣的小伙伴可以跟随小编... 目录使用python-pptx操作PPT文档安装python-pptx基础概念创建新的PPT文档查看

详解Java中三种状态机实现方式来优雅消灭 if-else 嵌套

《详解Java中三种状态机实现方式来优雅消灭if-else嵌套》这篇文章主要为大家详细介绍了Java中三种状态机实现方式从而优雅消灭if-else嵌套,文中的示例代码讲解详细,感兴趣的小伙伴可以跟... 目录1. 前言2. 复现传统if-else实现的业务场景问题3. 用状态机模式改造3.1 定义状态接口3

MySQL中优化CPU使用的详细指南

《MySQL中优化CPU使用的详细指南》优化MySQL的CPU使用可以显著提高数据库的性能和响应时间,本文为大家整理了一些优化CPU使用的方法,大家可以根据需要进行选择... 目录一、优化查询和索引1.1 优化查询语句1.2 创建和优化索引1.3 避免全表扫描二、调整mysql配置参数2.1 调整线程数2.

C#中SortedSet的具体使用

《C#中SortedSet的具体使用》SortedSet是.NETFramework4.0引入的一个泛型集合类,它实现了一个自动排序的集合,内部使用红黑树数据结构来维护元素的有序性,下面就来介绍一下如... 目录基础概念主要特性创建和初始化基本创建方式自定义比较器基本操作添加和删除元素查询操作范围查询集合运

C# Opacity 不透明度的具体使用

《C#Opacity不透明度的具体使用》本文主要介绍了C#Opacity不透明度的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录WinFormsOpacity以下是一些使用Opacity属性的示例:设置窗体的透明度:设置按钮的透

Java异常捕获及处理方式详解

《Java异常捕获及处理方式详解》异常处理是Java编程中非常重要的一部分,它允许我们在程序运行时捕获并处理错误或不预期的行为,而不是让程序直接崩溃,本文将介绍Java中如何捕获异常,以及常用的异常处... 目录前言什么是异常?Java异常的基本语法解释:1. 捕获异常并处理示例1:捕获并处理单个异常解释:

C#控制台程序同步调用WebApi实现方式

《C#控制台程序同步调用WebApi实现方式》控制台程序作为Job时,需同步调用WebApi以确保获取返回结果后执行后续操作,否则会引发TaskCanceledException异常,同步处理可避免异... 目录同步调用WebApi方法Cls001类里面的写法总结控制台程序一般当作Job使用,有时候需要控制

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据

在ASP.NET项目中如何使用C#生成二维码

《在ASP.NET项目中如何使用C#生成二维码》二维码(QRCode)已广泛应用于网址分享,支付链接等场景,本文将以ASP.NET为示例,演示如何实现输入文本/URL,生成二维码,在线显示与下载的完整... 目录创建前端页面(Index.cshtml)后端二维码生成逻辑(Index.cshtml.cs)总结