Mvp版本设计

设计一个EventBus静态类,在该类中列出所有需要注册和触发的事件


public static class EventBus
{
    public static Action<int, string> onEvent;
    public static Action<int> onEvent1;
    public static Action<string> onEvent2;
    public static Action<bool> onEvent3;
}

使用示例

public class EventBusExample : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

        EventBus.onEvent += OnEvent;
    }

    private void OnEvent(int arg1, string arg2)
    {
        Debug.Log("Event Triggered: " + arg1 + " " + arg2);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            EventBus.onEvent?.Invoke(1, "Space key pressed");
        }
    }
    private void OnDestroy() {
        EventBus.onEvent -= OnEvent;
    }
}

对于 EventBus.onEvent?.Invoke(1, "Space key pressed"); 可以封装成一个方法,这样可以避免每次都要去找是哪一个委托,这时的eventBus就是

public static class EventBus
{
    public static Action<int, string> onEvent;
    public static void TriggerEvent(int id, string message)
    {
        onEvent?.Invoke(id, message);
    }
    public static Action<int> onEvent1;
    public static void TriggerEvent1(int id)
    {
        onEvent1?.Invoke(id);
    }
    public static Action<string> onEvent2;
    public static void TriggerEvent2(string message)
    {
        onEvent2?.Invoke(message);
    }
    public static Action<bool> onEvent3;
    public static void TriggerEvent3(bool value)
    {
        onEvent3?.Invoke(value);
    }

}

上面示例中的触发事件就由 EventBus.onEvent?.Invoke(1, "Space key pressed"); 变成了 EventBus.TriggerEvent(1, "Space key pressed"); 到这里就已经是一个能满足小型项目使用的最简易的版本了。

初步重构

问题分析

可以看出每次需要增加一个事件时都要新建一个委托,写一个对应的方法,是很明显的重复劳动

每个方法传入的参数数量和类型都可能不一样,需要进行统一

解决思路

  1. 构建一个字典来存储所有的委托
  2. 将触发事件的方法统一成将结构或类作为参数

实践

用字典来存储所有的委托就需要给每个委托设置一个唯一的键值。那这个字典就应该是下面这样:

public static Dictionary<string, Action<object>> eventDictionary = new Dictionary<string, Action<object>>();

将参数统一为类,那每次需要触发一个事件就应该是下面这样:

EventBus.TriggerEvent("msgName", new EventMsg(1, "Space key pressed"));