消息系统的实现

消息系统的作用:

        在游戏开发中,观察者模式是一种非常常见的设计模式。观察者模式有效的避免了不同系统之间的耦合。通过观察者模式,A系统不必关注B系统内部的实现的迭代,只需关注B系统广播出去的消息即可,大大提高了开发效率和稳定性。

       

代码设计:

        设计思路:

        消息系统,顾名思义,需要有广播的地方,也需要有接收的地方。所以可以利用委托去管理不同系统的消息。对于发送方,需要提供广播的方法,即消息发送。对于接收方,需要提供消息订阅的方法,即注册消息。这样一来当一条消息广播时,所有订阅了次消息的模块都会收到次消息。并且,还需要提供取消订阅的方法,毕竟需不需要此消息是接收方决定的。

        与此同时,不同消息在广播的时候或许会携带自身数据,接收方需要利用这些数据进行后续的处理。但是不同消息携带的数据类型或者结构大不相同,因此需要利用泛型结构去适配各种各样的数据类型或者结构。

        最后,不同消息用枚举来区分。订阅同一个消息的委托(回调函数)都存储在统一结构中。

        设计模式:

        消息系统,单例模式,唯一实例,唯一控制。

        

        数据结构:

        使用字典去存储同一消息的委托(回调函数)。特别注意的是由于字典不支持泛型类型,所以需要通过定义对应的接口类。

        导图:

关键代码:

        MessageData.cs

        用来存储注册到消息系统的回调函数,本质就是个委托。因为字典不支持泛型,因此需要提供接口类。

public interface IMessageData
{
    
}


public class MessageData <T> : IMessageData
{
    public UnityAction<T> MessageEvents;

    public MessageData(UnityAction<T> action)
    {
        MessageEvents += action;
    }
}

        

        MessageManager.cs

        统一管理各个系统的消息,包括消息注册和反注册,消息广播。核心就是新建委托,回调函数添加至委托,调用委托。

public class MessageManager
{

    private static MessageManager _instance;

    public static MessageManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new MessageManager();
            }
            return _instance;
        }
    }


    private Dictionary<MessageEvent, IMessageData> _dictionaryMessage;

    private MessageManager()
    {
        _dictionaryMessage = new Dictionary<MessageEvent, IMessageData>();
    }

    public void Register<T>(MessageEvent key, UnityAction<T> action)
    {
        if (_dictionaryMessage.TryGetValue(key, out var previousAction))
        {
            if (previousAction is MessageData<T> messageData)
            {
                messageData.MessageEvents += action;

            }
        }
        else
        {
            MessageData<T> messageData = new MessageData<T>(action);
            _dictionaryMessage.Add(key, messageData);
        }
    }

    public void UnRegister<T>(MessageEvent key, UnityAction<T> action)
    {
        if (_dictionaryMessage.TryGetValue(key, out var previousAction))
        {
            if (previousAction is MessageData<T> MessageData)
            {
                MessageData.MessageEvents -= action;
            }
        }
    }

    public void Send<T>(MessageEvent key, T data)
    {
        if (_dictionaryMessage.TryGetValue(key, out var previousAction))
        {
            //(previousAction as MessageData<T>)?.MessageEvents.Invoke(data);

            if (previousAction is MessageData<T> MessageData)
            {
                MessageData.MessageEvents(data);
            }
        }
    }

    public void Clear()
    {
        _dictionaryMessage.Clear();
    }

}

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值