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

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

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“ 进行测试

 

posted @ 2022-06-25 16:58  赵不灰  阅读(147)  评论(0编辑  收藏  举报