您的位置:首页 > 其它

观察者设计模式学习!

2008-01-07 02:21 417 查看
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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: