旋风

Communication comes from our hears and heads! my msn:youpeizun@hotmail.com


导航

观察者设计模式学习!

Posted on 2008-01-07 02:21  xuanfeng  阅读(2791)  评论(5编辑  收藏  举报
 

1.1          意图

     定义对象间一对多的依赖关系,一个对象发生变化时,所有依赖它的对象都得到通知并被自动更新。Windows中的音量控制就是一个很典型的例子,可以找开多个调节音量的窗口,但注意观察可发现,当你在其中一个窗口中调节音量,其它窗口也会做出相关改变。这是因为每个窗口都定阅了音最大小这一实例的值,所以当音量大小改变时,它们就改变窗口中的显示状态。

1.2          使用场合

   观察者设计模式适当以下情形适用:

A.当一个抽象模型有两个方面,其中一个方面依赖开另一方面,将这二者封装在独立的对象中以使它们可以独立的改变和复用,降低它们这间的耦合性。

B.改变一个对象需要同时改变其它对象,但不知道有多少个对象有待改变。

1.3          静态结构图

观察者设计模式结构图如下:

A.      Subject:目标对象(接口或抽象类接供规范),即被观察的对象,要以有任意多个观察者观察一个目标。

B.      Observer::观察者对象(接口或抽象类接供规范),为观察者定义一个更新的接口.

C.      ConcreateSubject 具体的目标继承于目标抽象类或接口,当目标信息发生变化时通知所有具体的观察者。

D.     ConcreteObersever :具体的观察者继承于观察者抽象类或接口,依懒于具体的目标对象,根据具体目标信息更新具体的观察者。

接着据于一个简单的场景来DEMO一下观察者设计模式的使用。设计模式在实现时,它只是一种规范,实现起来应该是很灵活的,在此只抛下砖吧,如果有引玉的效果那是最好不过了。

场景:一家公司有很多客户,当公司的信息发生变化时,客户也会及时的更新该公司的信息,在这个例子里就把它打印出来吧!
1.4      代码

 1 namespace ConObserverDesigner
 2 {
 3     class Program
 4     {
 5         #region 公司目标抽象类
 6         public abstract class CompanyObject
 7         {
 8             ArrayList observers = new ArrayList();
 9             public void Attach(CustomerObserver observer)
10             {
11                 observers.Add(observer);
12             }
13             public void Detach(CustomerObserver observer)
14             {
15                 observers.Remove(observer);
16             }
17             public void Notify(string information)
18             {
19                 foreach (CustomerObserver observer in observers)
20                 {
21                     observer.Update(information);
22                 }
23             }
24         } 
25         #endregion
26         #region 客户观察者抽象类
27         public abstract class CustomerObserver
28         {
29             public abstract void Update(string information );
30 
31         } 
32         #endregion
33         #region 具体的目标公司对象
34         public class ConcreteCompanyObject : CompanyObject
35         {
36             string information = null;
37 
38             public ConcreteCompanyObject()
39             {
40 
41             }
42             public void ChangeInformation(string info)
43             {
44                 this.information = info;
45                 this.Notify(info);
46             }
47 
48         } 
49         #endregion
50         #region 具体的客户观察对象
51         public class ConcreteCustomerObserver : CustomerObserver
52         {
53             string name = null;
54 
55             public ConcreteCustomerObserver(string name)
56             {
57                 this.name = name;
58             }
59 
60             public string Name
61             {
62                 set { this.name = value; }
63                 get { return this.name; }
64             }
65             public override void Update(string info)
66             {
67                 this.Print(info);
68             }
69             private void Print(string info)
70             {
71                 Console.WriteLine("名为{0}更新了合作公司的信息。信息内容为:{1}", name, info);
72 
73             }
74 
75         } 
76         #endregion
77 
78         #region 测试类
79         static void Main(string[] args)
80         {   
81             //创建一个公司实例
82             ConcreteCompanyObject company = new ConcreteCompanyObject();
83             //创建两个客户实例
84             ConcreteCustomerObserver customer1 = new ConcreteCustomerObserver("First");
85             ConcreteCustomerObserver customer2 = new ConcreteCustomerObserver("Second");
86 
87             //给两个客户订阅信息
88             company.Attach(customer1);
89             company.Attach(customer2);
90             //更改公司信息
91             company.ChangeInformation("合作愉快!");
92             //预测:两个客户将打印相关信息
93 
94             Console.Read();
95         } 
96         #endregion
97     }
98 }
99 


1.5        .NET中采用委托和事件机制简化观察者模式的实现

委托和事件机制使得目标对象不需要知道观察者对象的存在,观察者若需要及时知道目标状态的变化,就得通过事件来定阅,并具体实现委托事件来达到更新观察者。

例如上面的例子,客户最终的目的就是显示合作公司的信息改变(如商品的库存情况的变化),用委托和事件机制来实现上面的场景,看看是不是简化灵活了许多。 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace ConObserver
 6 {
 7     public class Companys
 8     {
 9         string information = null;
10         public delegate void  ReportChange(string info);
11         public event ReportChange changeInfo;
12         public Companys()
13         { 
14         
15         }
16         public void ChangeInfomation(string info)
17         {
18             this.information = info;
19             //执行信息改变事件
20             changeInfo(info);
21         }
22     }
23     public class Customer
24     {
25         Companys company ;
26         public Customer()
27         { 
28         
29         }
30         public void InitCompanyObject(Companys com)
31         {
32             this.company = com;
33             //定阅合作公司信息改变事件
34             com.changeInfo += new Companys.ReportChange(com_changeInfo);
35         }
36         //公司信息改变委托办法
37         void com_changeInfo(string info)
38         {   
39             //执行打印信息。
40             this.Print(info);
41         }
42         private void Print(string info)
43         {
44             Console.WriteLine("名为{0}更新了合作公司的信息。信息内容为:{1}", name, info);
45 
46         }
47     }
48     
49 }