本文共 3168 字,大约阅读时间需要 10 分钟。
在代码编写中,我们经常会遇到类之间的消息传递,尤其是继承某些引擎对象(例如U3D)的方法,别的类直接调用会导致数据重置,这个时候就需要用到订阅者模式。
订阅者模式的作用,是当订阅对象发生变化的时候,可以将消息发布给每个订阅者。原理是建立一个抽象的消息类,所有事件在类中注册,并在订阅对象发生变化的时候,将对应消息分发给那些注册过订阅者。
代码如下:
using System;using System.Collections.Generic;////// 抽象的通知事件/// public abstract class EventsNotify{}////// 订阅通知类:使用函数Attach、Detach、Notify/// 一个回调函数/// public static class NotifierDispense{ private static readonly Dictionary> _dictionary = new Dictionary >(); /// /// 附加消息列表 /// /// /// public static void Attach(string _command, Action_callback) { Action _action; //如果获取到与指定命令关联的方法,将返回添加到方法中,并将其放入到列表中;否则直接将命令添加到列表中 if (_dictionary.TryGetValue(_command, out _action)) { _action += _callback; _dictionary[_command] = _action; } else { _dictionary.Add(_command, _callback); } } /// /// 分离消息列表 /// /// /// public static void Detach(string _command, Action_callback) { //如果字典中包含了指定命令,则将其注册方法在指定命令列表中删除 if (_dictionary.ContainsKey(_command)) { _dictionary[_command] -= _callback; } } /// /// 通知消息队列 /// /// /// public static void Notify(string _command, EventsNotify _notifyEvent) { Actionaction; //如果获取到与指定命令关联的方法,则调用通知事件 if (_dictionary.TryGetValue(_command, out action)) { action(_notifyEvent); } }}
订阅对象类(示例):
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Inform : MonoBehaviour { //内部类:消息传递类 public class InformEvent : EventsNotify { public static string Name => "InformEvent";//传递消息命令参数 public int Start { get; } public string Result { get; } public InformEvent(int _start,string _result)//所需要传递的消息 { Start = _start; Result = _result; } } // Use this for initialization void Start () { Debug.Log("我发了一条消息"); NotifierDispense.Notify(InformEvent.Name, new InformEvent(2019,"你好世界")); } // Update is called once per frame void Update () { }}
订阅类 :
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Subscription : MonoBehaviour { // Use this for initialization void Start () { Attach();//注册消息 } // Update is called once per frame void Update () { } ////// 注册添加消息:如果需要多个接收的话,就注册多个 /// void Attach() { NotifierDispense.Attach(Inform.InformEvent.Name, OnSubscription); } ////// 分离添加消息:如果注册多个接收的话,就分离多个 /// void Detach() { NotifierDispense.Detach(Inform.InformEvent.Name, OnSubscription); } ////// 接受到的消息 /// /// void OnSubscription(EventsNotify _notifyEvent) { Debug.Log("接收到消息"); var _updateEvent = _notifyEvent as Inform.InformEvent; if (null != _updateEvent) { Debug.Log(_updateEvent.Start); Debug.Log(_updateEvent.Result); } }}
最终打印结果:
由图可清晰的看到,当被订阅对象发布一条消息的时候,订阅者可以接收到了这条消息,并可以将传递的参数应用于订阅类的代码中。
转载地址:http://hxwli.baihongyu.com/