C#学习笔记-观察者模式
标签:记录 将不 设置 目的 抽象方法 技术 知识点 不一致 影响
题目1:几个同事为了在上班期间偷偷看休息,做点其他的事情,就和小秘偷偷联系了一下,如果老板回来了,就麻烦小秘偷偷通知一声,这样方便大家及时变更自己的工作状态。
分析:
根据题目分析,首先明确,肯定会有两个类:小秘类和同事类,分别描述与记录两种类型的人和行为。
需要注意的是:小秘与同事构建联系的时候,一个小秘可能对应多位同事,所以这时需要利用List。
实现:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Secretary lady = new Secretary();
6 StockObserver num1 = new StockObserver("A", lady);
7 StockObserver num2 = new StockObserver("B", lady);
8
9 lady.Attach(num1);
10 lady.Attach(num2);
11
12 lady.SecretAction="boss is back";
13 lady.Notify();
14
15 Console.Read();
16 }
17 }
18
19 ///
20 /// 小秘
21 /// 1.记下需要联系的同事们List
22 /// 2.增加需要联系的人员
23 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
24 /// 4.秘密通知同事,老板回来了
25 ///
26 class Secretary
27 {
28 IList stockOb = new List();
29 private string action;
30
31 public string SecretAction
32 {
33 get
34 {
35 return action;
36 }
37
38 set
39 {
40 action = value;
41 }
42 }
43
44 //增加需要联系的人员
45 public void Attach(StockObserver ob)
46 {
47 stockOb.Add(ob);
48 }
49
50 //减少需要联系的人员
51 public void Detach(StockObserver ob)
52 {
53 stockOb.Remove(ob);
54 }
55
56 //小秘通知了同事后,同事赶紧自行更改工作状态
57 public void Notify()
58 {
59 foreach (StockObserver o in stockOb)
60 o.Update();
61 }
62 }
63
64 ///
65 /// 看股票的同事
66 /// 1.联系小秘,和小秘保持良好关系
67 /// 2.根据小秘的偷偷通知修改自己的工作状态
68 ///
69 class StockObserver
70 {
71 private string name;
72 private Secretary sec;
73
74 public StockObserver(string name,Secretary sec)
75 {
76 this.name = name;
77 this.sec = sec;
78 }
79 public void Update()
80 {
81 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sec.SecretAction, name);
82 }
83 }
View Code
题目2:由于同事们人数众多,所以大家休闲的方式并不一致。
分析:
同事们的休闲方式不同,他们彼此之间存在共同点与不同点。
他们的共同点在于都需要与小秘联系且更新工作状态,同时他们的不同点也在于更新工作状态。
所以相同点就不需要在子类中赘述,所以通过抽象类来将不同的方法设为抽象即可。
实现:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Secretary lady = new Secretary();
6 StockObserver num1 = new StockObserver("A", lady);
7 NBAObserver num2 = new NBAObserver("B", lady);
8
9 lady.Attach(num1);
10 lady.Attach(num2);
11
12 lady.SecretAction = "boss is back";
13 lady.Notify();
14
15 Console.Read();
16 }
17 }
18
19 ///
20 /// 小秘
21 /// 1.记下需要联系的同事们List
22 /// 2.增加需要联系的人员
23 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
24 /// 4.秘密通知同事,老板回来了
25 ///
26 class Secretary
27 {
28 IList observers = new List();
29 private string action;
30
31 public string SecretAction
32 {
33 get
34 {
35 return action;
36 }
37
38 set
39 {
40 action = value;
41 }
42 }
43
44 //增加需要联系的人员
45 public void Attach(Observers ob)
46 {
47 observers.Add(ob);
48 }
49
50 //减少需要联系的人员
51 public void Detach(Observers ob)
52 {
53 observers.Remove(ob);
54 }
55
56 //小秘通知了同事后,同事赶紧自行更改工作状态
57 public void Notify()
58 {
59 foreach (Observers o in observers)
60 o.Update();
61 }
62 }
63
64 ///
65 /// 观察者类
66 /// 抽象类
67 /// 偷偷玩的同事的状态都不同,他们的共同点就是1.与小秘联系,2.更新工作状态
68 /// 不同点在于更新状态前不同,所以更新工作状态设置为抽象方法即可
69 ///
70 abstract class Observers
71 {
72 protected string name;
73 protected Secretary sec;
74
75 public Observers(string name,Secretary sec)
76 {
77 this.name = name;
78 this.sec = sec;
79 }
80
81 public abstract void Update();
82 }
83
84
85 ///
86 /// 看股票的同事
87 /// 继承于观察者类
88 /// 根据小秘的偷偷通知修改自己的工作状态
89 ///
90 class StockObserver:Observers
91 {
92 public StockObserver(string name, Secretary sec)
93 : base(name, sec)
94 {
95 }
96
97 public override void Update()
98 {
99 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sec.SecretAction,name);
100 }
101 }
102
103 ///
104 /// 看NBA节目的同事
105 /// 继承于观察者类
106 /// 根据小秘的偷偷通知修改自己的工作状态
107 ///
108 class NBAObserver : Observers
109 {
110 public NBAObserver(string name, Secretary sec)
111 : base(name, sec)
112 {
113 }
114
115 public override void Update()
116 {
117 Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sec.SecretAction, name);
118 }
119 }
View Code
题目3:如果小秘突然有事情变得特别忙的时候,就没有了通知者,而此刻老板突然回来了,所以老板本身就变成了临时的通知者。
分析:
老板本身变成了临时的通知者,虽然这个故事很不幸,但是客观分析,此刻老板的作用于小秘是一样的,所以老板应该和小秘继承于同一种父类。
由于老板需要与观察者联系,而此刻的观察者已是抽象类,所以老板的父类不能再为抽象类了。
原因如下:
故此,老板和小秘只能通过接口来实现了。
实现:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Boss boss = new Boss();
6
7
8 Secretary lady = new Secretary();
9 StockObserver num1 = new StockObserver("A", lady);
10 NBAObserver num2 = new NBAObserver("B", lady);
11
12 //lady没来的及通知两位同事
13 lady.Detach(num1);
14 lady.Detach(num2);
15
16 //现在的通知者就变成了boss
17 boss.Attach(num1);
18 boss.Attach(num2);
19
20 //num2没有看见boss回来,所以boss没来的及通知他
21 boss.Detach(num2);
22
23 boss.SecretAction = "boss is back";
24 boss.Notify();
25
26 Console.Read();
27 }
28 }
29
30 ///
31 /// 通知者的接口
32 /// 不能用抽象类
33 ///
34 interface Subject
35 {
36 void Attach(Observers ob);
37 void Detach(Observers ob);
38 void Notify();
39 string SecretAction
40 {
41 get;set;
42 }
43 }
44
45 class Boss : Subject
46 {
47 IList observers = new List();
48 private string action;
49
50 public string SecretAction
51 {
52 get
53 {
54 return action;
55 }
56
57 set
58 {
59 action = value;
60 }
61 }
62
63 //增加需要联系的人员
64 public void Attach(Observers ob)
65 {
66 observers.Add(ob);
67 }
68
69 //减少需要联系的人员
70 public void Detach(Observers ob)
71 {
72 observers.Remove(ob);
73 }
74
75 //大家看见boss回来后,同事赶紧自行更改工作状态
76 public void Notify()
77 {
78 foreach (Observers o in observers)
79 o.Update();
80 }
81 }
82
83 ///
84 /// 小秘:继承于接口
85 /// 1.记下需要联系的同事们List
86 /// 2.增加需要联系的人员
87 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
88 /// 4.秘密通知同事,老板回来了
89 ///
90 class Secretary:Subject
91 {
92 IList observers = new List();
93 private string action;
94
95 public string SecretAction
96 {
97 get
98 {
99 return action;
100 }
101
102 set
103 {
104 action = value;
105 }
106 }
107
108 //增加需要联系的人员
109 public void Attach(Observers ob)
110 {
111 observers.Add(ob);
112 }
113
114 //减少需要联系的人员
115 public void Detach(Observers ob)
116 {
117 observers.Remove(ob);
118 }
119
120 //小秘通知了同事后,同事赶紧自行更改工作状态
121 public void Notify()
122 {
123 foreach (Observers o in observers)
124 o.Update();
125 }
126 }
127
128 ///
129 /// 观察者类
130 /// 抽象类
131 /// 偷偷玩的同事的状态都不同,他们的共同点就是1.与小秘联系,2.更新工作状态
132 /// 不同点在于更新状态前不同,所以更新工作状态设置为抽象方法即可
133 ///
134 abstract class Observers
135 {
136 protected string name;
137 protected Secretary sec;
138
139 public Observers(string name, Secretary sec)
140 {
141 this.name = name;
142 this.sec = sec;
143 }
144
145 public abstract void Update();
146 }
147
148
149 ///
150 /// 看股票的同事
151 /// 继承于观察者类
152 /// 根据小秘的偷偷通知修改自己的工作状态
153 ///
154 class StockObserver : Observers
155 {
156 public StockObserver(string name, Secretary sec)
157 : base(name, sec)
158 {
159 }
160
161 public override void Update()
162 {
163 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sec.SecretAction, name);
164 }
165 }
166
167 ///
168 /// 看NBA节目的同事
169 /// 继承于观察者类
170 /// 根据小秘的偷偷通知修改自己的工作状态
171 ///
172 class NBAObserver : Observers
173 {
174 public NBAObserver(string name, Secretary sec)
175 : base(name, sec)
176 {
177 }
178
179 public override void Update()
180 {
181 Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sec.SecretAction, name);
182 }
183 }
View Code
附:
实现:
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Boss boss = new Boss();
6 Secretary lady = new Secretary();
7
8 StockObserver num1 = new StockObserver("A", boss);
9 NBAObserver num2 = new NBAObserver("B", boss);
10
11 //将“看股票”的“关闭股票程序”方法和“看NBA者”的“关闭NBA直播”的方法
12 //挂钩到老板的“更新”上,也就是将两种不同类的不同方法委托给老板类的更新了。
13 boss.Update += new EventHandler(num1.CloseStockMarket);
14 boss.Update += new EventHandler(num2.CloseNBADirectSeeding);
15
16 boss.SecretAction = "boss is back";
17 boss.Notify();
18
19 Console.Read();
20 }
21 }
22
23 ///
24 /// 通知者的接口
25 /// 不能用抽象类
26 /// 现在抽象通知者由于不下网依赖抽象观察者,所以“增加”和“减少”的方法就没有必要了
27 ///
28 interface Subject
29 {
30 void Notify();
31 string SecretAction
32 {
33 get; set;
34 }
35 }
36
37 ///
38 /// 委托就是一种引用方法的类型。
39 /// 一旦为委托分配了方法,委托将于该方法具有完全相同的行为
40 /// 委托方法的使用可以像任何其他方法一样,具有参数和返回值。
41 /// 委托可以看做是对函数的抽象,是函数的‘类’,委托的实例将代表一个具体的函数
42 ///
43 /// 一个委托可以搭载多个方法,所有的方法被依次唤起
44 /// 最重要的是,它可以使得委托对象所搭载的方法并不需要属于同一个类
45 ///
46 /// 委托对象所搭载的所有方法必须具有相同的原型和形式,也就是有相同的参数列表和返回值类型
47 ///
48 delegate void EventHandler(); //委托
49
50 class Boss : Subject
51 {
52 public event EventHandler Update;
53
54 private string action;
55
56 public string SecretAction
57 {
58 get
59 {
60 return action;
61 }
62
63 set
64 {
65 action = value;
66 }
67 }
68
69 //大家看见boss回来后,同事赶紧自行更改工作状态
70 public void Notify()
71 {
72 Update();
73 }
74 }
75
76 ///
77 /// 小秘:继承于接口
78 /// 1.记下需要联系的同事们List
79 /// 2.增加需要联系的人员
80 /// 3.减少联系人员(有可能没有通知到,有可能人员辞职等)
81 /// 4.秘密通知同事,老板回来了
82 ///
83 class Secretary : Subject
84 {
85 public event EventHandler Update;
86
87 private string action;
88
89 public string SecretAction
90 {
91 get
92 {
93 return action;
94 }
95
96 set
97 {
98 action = value;
99 }
100 }
101
102
103 //小秘通知了同事后,同事赶紧自行更改工作状态
104 public void Notify()
105 {
106 Update();
107 }
108 }
109
110 ///
111 /// 看股票的同事
112 /// 根据小秘的偷偷通知修改自己的工作状态
113 ///
114 class StockObserver
115 {
116 private string name;
117 private Subject sub;
118
119 public StockObserver(string name,Subject sub)
120 {
121 this.name = name;
122 this.sub = sub;
123 }
124
125 public void CloseStockMarket()
126 {
127 Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SecretAction, name);
128 }
129 }
130
131 ///
132 /// 看NBA节目的同事
133 /// 根据小秘的偷偷通知修改自己的工作状态
134 ///
135 class NBAObserver
136 {
137 private string name;
138 private Subject sub;
139
140 public NBAObserver(string name,Subject sub)
141 {
142 this.name = name;
143 this.sub = sub;
144 }
145
146 public void CloseNBADirectSeeding()
147 {
148 Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SecretAction, name);
149 }
150 }
View Code
总结:
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
观察者模式所做的工作其实就是在接触耦合。让耦合的双方依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
委托:就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看作是对函数的抽象,是函数的‘类’,委托的实例将代表一个具体的函数。
一个委托可以搭载多个方法,所有方法被依次唤起。
委托对象所搭载的方法并不需要属于同一个类。
注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。
C#学习笔记-观察者模式
标签:记录 将不 设置 目的 抽象方法 技术 知识点 不一致 影响
原文地址:http://www.cnblogs.com/Aries-rong/p/7728060.html
评论