• 观察者模式之通用消息发布与订阅


    观察者模式:当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
    主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

    TestCommonEvent.cs

     1 using System.Collections.Generic;
     2 
     3 public class TestCommonEvent : System.IDisposable
     4 {
     5     public delegate void OnActionHandler(object obj);
     6     public Dictionary<ushort, LinkedList<OnActionHandler>> dic = new Dictionary<ushort, LinkedList<OnActionHandler>>();
     7 
     8     /// <summary>
     9     /// 添加监听
    10     /// </summary>
    11     /// <param name="key"></param>
    12     /// <param name="actionEvent"></param>
    13     public void AddEventListener(ushort key, OnActionHandler actionEvent)
    14     {
    15         dic.TryGetValue(key, out LinkedList<OnActionHandler> list);
    16         if (list == null)
    17         {
    18             list = new LinkedList<OnActionHandler>();
    19             dic[key] = list;
    20         }
    21         list.AddLast(actionEvent);
    22     }
    23 
    24     /// <summary>
    25     /// 移除监听
    26     /// </summary>
    27     /// <param name="key"></param>
    28     /// <param name="actionEvent"></param>
    29     public void RemoveEventListener(ushort key, OnActionHandler actionEvent)
    30     {
    31         if (dic.TryGetValue(key, out LinkedList<OnActionHandler> list))
    32         {
    33             list.Remove(actionEvent);
    34             if (list.Count == 0)
    35             {
    36                 dic.Remove(key);
    37             }
    38         }
    39     }
    40 
    41     /// <summary>
    42     /// 派发
    43     /// </summary>
    44     /// <param name="key"></param>
    45     /// <param name="obj"></param>
    46     public void Dispatch(ushort key, object obj)
    47     {
    48         if (dic.TryGetValue(key, out LinkedList<OnActionHandler> list))
    49         {
    50             for (var v = list.First; v != null; v = v.Next)
    51             {
    52                 v.Value?.Invoke(obj);
    53             }
    54         }
    55     }
    56 
    57     public void Dispose()
    58     {
    59         dic.Clear();
    60     }
    61 }

    TestEventManager.cs

     1 public class TestEventManager : System.IDisposable
     2 {
     3     public TestCommonEvent commonEvent;
     4     public TestEventManager()
     5     {
     6         commonEvent = new TestCommonEvent();
     7     }
     8 
     9     public void Init()
    10     {
    11     }
    12 
    13     public void Dispose()
    14     {
    15         commonEvent.Dispose();
    16     }
    17 }

     

    测试用例:

    建3个物体 分别挂上对应的脚本:

     Xiaozhang.cs

     1 using UnityEngine;
     2 
     3 public class Xiaozhang : MonoBehaviour
     4 {
     5     void Update()
     6     {
     7         if (Input.GetKeyDown(KeyCode.F))
     8         {
     9             string times = "16:30";
    10             if (TestGameEntry.EventMgr != null)
    11             {
    12                 TestGameEntry.EventMgr.commonEvent.Dispatch(TestCommonEventId.xiaozhangFangXue, times);
    13             }
    14         }
    15     }
    16 }
    View Code

      Xiaohong.cs

     1 using UnityEngine;
     2 
     3 public class Xiaohong : MonoBehaviour
     4 {
     5     void Start()
     6     {
     7         if (TestGameEntry.EventMgr != null)
     8         {
     9             TestGameEntry.EventMgr.commonEvent.AddEventListener(TestCommonEventId.xiaozhangFangXue, Xiaozhangfangxue);
    10         }
    11     }
    12 
    13     private void Xiaozhangfangxue(object obj)
    14     {
    15         Debug.LogError("小张放学了,我去找他玩");
    16     }
    17 
    18     private void OnDestroy()
    19     {
    20         TestGameEntry.EventMgr.commonEvent.RemoveEventListener(TestCommonEventId.xiaozhangFangXue, Xiaozhangfangxue);
    21     }
    22 }
    View Code

    mama.cs

     1 using UnityEngine;
     2 
     3 public class Mama : MonoBehaviour
     4 {
     5     void Start()
     6     {
     7         if (TestGameEntry.EventMgr != null)
     8         {
     9             TestGameEntry.EventMgr.commonEvent.AddEventListener(TestCommonEventId.xiaozhangFangXue, Xiaozhangfangxue);
    10         }
    11     }
    12     private void Xiaozhangfangxue(object obj)
    13     {
    14         Debug.LogError("小张" + obj.ToString() + "点放学了,我得去接孩子了");
    15     }
    16 
    17     private void OnDestroy()
    18     {
    19         TestGameEntry.EventMgr.commonEvent.RemoveEventListener(TestCommonEventId.xiaozhangFangXue, Xiaozhangfangxue);
    20     }
    21 }
    View Code

    TestCommonEventId.cs

    public class TestCommonEventId
    {
        public const ushort xiaozhangFangXue = 10001;
    }

     按键 ”F“ 进行测试

     

  • 相关阅读:
    二叉树的最大深度与最小深度
    【C++学习笔记】由 const char* 引出的一系列问题
    【C++学习笔记】标准库容器Vector可变长度实现原理
    Python数据可视化之Matplotlib学习笔记
    python读取excel文件—xlrd
    ubuntu14.04下嵌入式工作环境搭建
    ubuntu14.04下交叉编译器的安装
    挂载nfs系统问题之: Root-NFS: Server returned error -13 while mounting
    关于开发板不能ping通外网IP
    Socket的协议地址属性
  • 原文地址:https://www.cnblogs.com/zhaolaosan/p/16411805.html
Copyright © 2020-2023  润新知