观察者模式之通用消息发布与订阅
观察者模式:当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
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 }
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 }
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 }
TestCommonEventId.cs
public class TestCommonEventId
{
public const ushort xiaozhangFangXue = 10001;
}
按键 ”F“ 进行测试