思考并回答以下问题:
最近看游戏设计模式,当看到观察者模式时被搞得云里雾里的,什么观察者,被观察者,抽象观察者,抽象被观察者。听着这些词就觉得可怕,其实理解以后还是比较简单的。
当我们玩游戏时,经常会出现一些事件,而这个事件可能会影响到许多个模块时就可以用到观察者模式。例如:当我们在游戏中被丧尸咬时,我们就触发了变身丧尸的特殊事件,此时我们本身的人物模型可能会改变,同时系统的背景音乐和战斗方式也可能改变。此时就是一个事件影响多个模块的状况了,就可以用到观察者模式,废话不多说直接上代码。1
2
3
4
5
6
7/// <summary>
/// 抽象观察者,定义接收通知的接口
/// </summary>
public abstract class Observer
{
public abstract void OnNotify();
}
首先我们定义一个抽象类Observer,Obserber中我们定义抽象方法,这就是当我们接收到事件时要执行的方法了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33/// <summary>
/// 抽象主题(抽象被观察者)类,内含观察者列表和实现接收各种通知
/// </summary>
public abstract class Subject
{
private List<Observer> observerList = new List<Observer>();
/// <summary>
/// 添加观察者
/// </summary>
/// <param name="observer"></param>
public void AddObserver(Observer observer)
{
observerList.Add(observer);
}
/// <summary>
/// 移除观察者
/// </summary>
/// <param name="observer"></param>
public void RemoveObserver(Observer observer)
{
observerList.Remove(observer);
}
/// <summary>
/// 推送通知
/// </summary>
public void Notify()
{
foreach (Observer o in observerList)
{
o.OnNotify();
}
}
}
然后是定义一个抽象主题类,抽象主题类中包含添加和移除Observer的方法,定义一个Notify方法作为推送方法。我们推送消息到Observer链表中的各个Observer方法,Observer方法就开始执行监听的方法了。1
2
3
4
5
6
7
8
9
10
11
12/// <summary>
/// 具体主题(被观察者)类,实现要推送的主题
/// </summary>
public class Boss : Subject
{
private string _command;
public string Command
{
get { return _command; }
set { _command = value; }
}
}
具体主题类是真正实现要推送的消息,我们确认一个事件是否推送和如何推送消息的方法等都是在这里完成的。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31/// <summary>
/// 观察者类,当接收到推送通知时,实现各个模块功能
/// </summary>
public class EmployeeA:Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeA(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下达命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
观察者类,这个是获取推送消息时真正要执行的一段程序,在这里具体化要执行的程序的工作内容。
下面是完整的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
public class ObserverPattern : MonoBehaviour {
/// <summary>
/// 抽象观察者,定义接收通知的接口
/// </summary>
public abstract class Observer
{
public abstract void OnNotify();
}
/// <summary>
/// 抽象主题(抽象被观察者)类,内含观察者列表和实现接收各种通知
/// </summary>
public abstract class Subject
{
private List<Observer> observerList = new List<Observer>();
/// <summary>
/// 添加观察者
/// </summary>
/// <param name="observer"></param>
public void AddObserver(Observer observer)
{
observerList.Add(observer);
}
/// <summary>
/// 移除观察者
/// </summary>
/// <param name="observer"></param>
public void RemoveObserver(Observer observer)
{
observerList.Remove(observer);
}
/// <summary>
/// 推送通知
/// </summary>
public void Notify()
{
foreach (Observer o in observerList)
{
o.OnNotify();
}
}
}
/// <summary>
/// 具体主题(被观察者)类,实现要推送的主题
/// </summary>
public class Boss : Subject
{
private string _command;
public string Command
{
get { return _command; }
set { _command = value; }
}
}
/// <summary>
/// 观察者类,当接收到推送通知时,实现各个模块功能
/// </summary>
public class EmployeeA:Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeA(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下达命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
public class EmployeeB : Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeB(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下达命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
public class EmployeeC : Observer
{
private string _name;
private string _doSomething;
private Boss _boss;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string DoSomething
{
get { return _doSomething; }
set { _doSomething = value; }
}
public EmployeeC(Boss boss)
{
_boss = boss;
}
public override void OnNotify()
{
if (_boss.Command == "下达命令")
{
Debug.Log("我是" + _name + "我要" + DoSomething);
}
}
}
void Start()
{
Boss boss = new Boss();
EmployeeA employeeA = new EmployeeA(boss);
EmployeeA employeeB = new EmployeeA(boss);
EmployeeA employeeC = new EmployeeA(boss);
employeeA.Name = "雇员A";
employeeA.DoSomething = "打扫卫生";
employeeB.Name = "雇员B";
employeeB.DoSomething = "整理货物";
employeeC.Name = "雇员C";
employeeC.DoSomething = "清算账目";
boss.AddObserver(employeeA);
boss.AddObserver(employeeB);
boss.AddObserver(employeeC);
boss.Command = "下达命令";
boss.Notify();
}
}
其实观察者模式可以这么理解,我们不妨把它看做是一个超市,具体观察者是超市的老板,老板要下达命令给员工,具体主题是超市的员工,员工收到了老板下达的命令就开始工作了,抽象主题就是一个任务表,任务表中包含所需要工作员工的名单,我们要告诉名单中的员工你别偷懒了,开始干活吧,抽象观察者就是一个工作的大致内容,例如:年底盘查,但是我们不去关心年底盘查具体的步骤该怎么做,怎么做的事情由员工自己来负责。