设计模式笔记8: 观察者模式

1.1  定义

  定义了一种一对多的依赖关系,让多个观察者同时监听一个对象,但这个对象发生变化时,会通知所有观察者对象,使他们能够更新自己。

 

1.2  类图

 

 

1.3  代码

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 观察者模式
 8 {
 9     // 委托  
10     delegate void EventHandler();
11 
12     // 此时若需要增加一个看NBA的同事,就需要修改原有的类,违背开放封闭原则,而且此时他们都依赖于细节又违背了依赖倒转原则
13     // 所以我们抽象一个父类解决这个问题
14 
15     // 观察者父类
16     abstract class Observer
17     {
18         protected string name;
19         protected Subject sub;
20 
21         public Observer(string name, Subject sub)
22         {
23             this.name = name;
24             this.sub = sub;
25         }
26 
27         // public abstract void Update();
28     }
29 
30     // 看股票观察者
31     class StockObserver : Observer
32     {
33 
34         public StockObserver(string name, Subject sub)
35             : base(name, sub)
36         {
37 
38         }
39         // 通知
40         public void CloseStockMarket()
41         {
42             Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, this.name);
43         }
44     }
45 
46 
47     // 看NBA观察者
48     class NBAObserver : Observer
49     {
50         public NBAObserver(string name, Subject sub) : base(name, sub) { }
51         public void CloseNBAPlay()
52         {
53             Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, this.name);
54         }
55     }
56 
57 
58 
59     // 通知者接口
60     abstract class Subject
61     {
62         // 委托
63         public EventHandler Update;
64         public abstract void Notify();
65         public string SubjectState { get; set; }
66     }
67 
68     // 老板 实现通知者接口
69     class Boss : Subject
70     {
71         public override void Notify()
72         {
73             Update();
74         }
75     }
76 
77     // 前台秘书
78     // 前台秘书类也是一个具体的依赖,因为通知的对象可能是老板或其他对象。所以也需要抽象出来。
79     class Secretary : Subject
80     {
81         // 通知
82         public override void Notify()
83         {
84             Update();
85         }
86     }
87 
88 
89 
90 
91 }
View Code

 

调用:

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace 观察者模式
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             // 前台
14             Subject s = new Boss();
15             // 看股票的同事
16             StockObserver t1 = new StockObserver("熊大", s);
17             NBAObserver t2 = new NBAObserver("熊二", s);
18 
19             // 前台记录两个同事
20             //s.Attach(t1);
21             //s.Attach(t2);
22             //s.Detach(t1); // 熊大没有被通知到
23             // 老板回来通知同事
24             s.Update += new EventHandler(t1.CloseStockMarket);
25             s.Update += new EventHandler(t2.CloseNBAPlay);
26             s.SubjectState  = "我胡汉三回来了!";
27             s.Notify();
28 
29         }
30     }
31 }
View Code

 

 

1.4  总结

  我们定义观察者和通知者和通知者两个抽象父类都是为了面向抽象编程,以后再增加新的功能时增加新的类,而不修改原有的子类。 还有一个耦合:我们通知者对象通知观察者时执行的方法都是同一个方法。方法的执行体虽然已经被观察者重写,但是名字还是一致的。所以我们在通知者中增加了委托类型的成员,只需要将通知观察者的方法,注册给通知者的委托成员。这样就能完全自定义执行的方法了。

  

posted @ 2014-12-07 16:03  AfreadHuang  阅读(225)  评论(0编辑  收藏  举报