Skip to content

观察者设计模式2

683 字约 2 分钟

设计模式

2024-12-12

在前面的 文章 我们已经知道了如何简单地使用观察者设计模式,同时也留下了一些问题:带参数的事件、如何优化写法。细心的同学就会发现我们前面写的Event.cs用的是 partial 关键字,我们可以在Event.cs中处理多个数据。

Event.T.cs
public partial class Event<T> : IEvent
{
    private readonly List<Action<T>> subscribers;
    public Event(string name) : base(name)
    {
        subscribers = new List<Action<T>>();
    }

    /// <summary>
    /// 订阅的活动依次执行
    /// </summary>
    public void Call(T pram)
    {
        for (int i = subscribers.Count - 1; i >= 0; i--)
        {
            subscribers[i].Invoke(pram); // 执行
        }
    }

    public static Event<T> operator +(Event<T> e, Action<T> action)
    {
        e.CheckName(action);
        e.subscribers.Add(action);
        return e;
    }

    public static Event<T> operator -(Event<T> e, Action<T> action)
    {
        e.subscribers.Remove(action);
        return e;
    }

    private void CheckName(Action<T> action)
    {
        // 如果已经包含了这个名字的action就抛出
        if (subscribers.Contains(action))
        {
            ThrowNameException();
        }
    }
}

Event.T.cs中只需要增加一个泛型就可以用来传参了,如果有两个或更多的参数也是同理,Event.TT.csEvent.TTT.cs


使用反射给Events中的静态参数实例化。我们可以用反射给 public static 修饰的 Event 全部自动实例化,所以在Events.Input.cs就不需要再实例化了。不知道反射也没关系,只需要知道加了Events.cs中的代码之后,后面的事件就不需要实例化就可以直接使用了。

Events.Input.cs
public partial class Events
{
    public static Event<int> PlayerSwapWeapon;// 切换武器
    public static Event FireRequest; // 开枪的请求
    public static Event ReloadRequest; // 换弹夹的请求
    public static Event JumpRequest; // 跳跃的请求
}