事件总线
1、概述
事件总线(EventBus)是一个基于观察者模式的通信机制,用于实现不同模块间的解耦通信。本实现采用静态门面类+内部实现类的双层架构设计,既保证了业务端使用的便捷性,又保持了内部实现的灵活性和可维护性。
2、架构设计
静态门面类(EventBus)
设计目的:为业务代码提供简洁统一的API接口,隐藏内部实现细节。
核心特性:
完全静态方法,无需实例化即可使用
方法签名简单明了,降低使用门槛
作为业务层与实现层之间的桥梁
using System;
/// <summary>
/// 事件总线静态门面类,提供事件订阅、取消订阅和发布的统一接口。
/// </summary>
public static class EventBus
{
// 订阅指定类型的事件。
public static void Subscribe(string eventType, Action<object> callback)
=> EventBusImpl.Subscribe(eventType, callback);
// 取消订阅指定类型的事件。
public static void Unsubscribe(string eventType, Action<object> callback)
=> EventBusImpl.Unsubscribe(eventType, callback);
// 发布指定类型的事件,并分发数据至所有订阅者。
public static void Publish(string eventType, object data = null)
=> EventBusImpl.Publish(eventType, data);
}
内部实现类(EventBusImpl)
设计目的:封装事件管理的核心逻辑,支持未来的功能扩展。
核心特性:
使用字典存储事件订阅关系
实现事件的订阅、取消订阅和发布功能
内部实现,对外部透明
using System;
using System.Collections.Generic;
/// <summary>
/// 消息总线实现类,负责事件的订阅、取消订阅及分发功能。
/// </summary>
internal static class EventBusImpl
{
// 事件订阅者集合。
private static readonly Dictionary<string, List<Action<object>>> _subscribers = new();
// 订阅指定类型的事件。
public static void Subscribe(string eventType, Action<object> callback)
{
if (!_subscribers.ContainsKey(eventType))
_subscribers[eventType] = new List<Action<object>>();
if (!_subscribers[eventType].Contains(callback))
_subscribers[eventType].Add(callback);
}
// 取消订阅指定类型的事件。
public static void Unsubscribe(string eventType, Action<object> callback)
{
if (_subscribers.ContainsKey(eventType))
_subscribers[eventType].Remove(callback);
}
// 发布指定类型的事件,通知所有已订阅的回调方法。
public static void Publish(string eventType, object data = null)
{
if (_subscribers.ContainsKey(eventType))
{
var callbacks = new List<Action<object>>(_subscribers[eventType]);
foreach (var callback in callbacks)
{
callback?.Invoke(data);
}
}
}
}
3、核心功能说明
事件订阅(Subscribe)
// 业务端使用示例
EventBus.Subscribe("PlayerDeath", OnPlayerDeathHandler);
private void OnPlayerDeathHandler(object data)
{
// 处理玩家死亡事件
}
实现机制:
按事件类型分组存储回调方法
自动去重,避免重复订阅
线程安全的回调列表管理
事件发布(Publish)
// 业务端使用示例
EventBus.Publish("PlayerDeath", new { score = 100, reason = "enemy" });
实现机制:
遍历指定事件类型的所有订阅者
使用副本列表进行回调,避免在迭代过程中修改原始集合
支持空数据传递
事件取消订阅(Unsubscribe)
// 业务端使用示例
EventBus.Unsubscribe("PlayerDeath", OnPlayerDeathHandler);
实现机制:
精确匹配事件类型和回调方法
安全的移除操作,避免空引用异常
4、特性说明
门面模式优势
简化接口:业务代码只需关注
EventBus
静态类降低耦合:业务模块间通过事件通信,减少直接依赖
易于维护:内部实现变更不影响业务代码
性能优化
使用
Dictionary<string, List<Action<object>>>
高效存储订阅关系发布时创建回调列表副本,确保迭代安全
避免不必要的内存分配
类型安全
使用强类型的事件类型标识
统一的回调签名,便于调试和错误追踪
5、使用场景
游戏逻辑通信
UI与游戏逻辑的交互
角色系统与战斗系统的通信
场景切换事件通知
系统模块解耦
成就系统与游戏进度的解耦
音效系统与游戏事件的解耦
存档系统与游戏状态的解耦
6、注意事项
事件类型管理:建议使用常量或枚举管理事件类型,避免字符串硬编码
内存泄漏:在对象销毁时务必取消相关事件订阅
性能考虑:避免在频繁触发的事件中执行复杂逻辑
调试建议:可为事件总线添加日志功能,便于调试事件流
事件总线类提供了轻量级、高性能的模块通信解决方案,是构建可维护游戏架构的重要基础工具。