设计模式笔记--行为型模式之七Observer--观察者

意图:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这一模式中的关键对象是目标和观察者。这种交互也称为发布订阅。

适用性:

1当一个抽象模型有两个方面,其中一个方面依赖于另外一个方面。将这二者封装在独立的对象中以使得它们可以各自独立的改变和复用。

2当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象待改变

3当一个对象必须通知其他对象,而它又不能假定其他对象是谁,即不希望这些对象是紧耦合的。

效果:

1目标和观察者之间的抽象耦合

2支持广播通信

3意外的更新

实现:

1创建目标到其观察之者间的映射,最简单的方法是显式的在目标中保存对他们的引用。或者用关联查找机制来维护目标到观察者的映射。

2观察多个目标

3谁触发更新

A由目标对象的状态设定操作在改变目标对象的状态后自动调用notify

B让客户负责在适当的时候调用Notify

4对已删除目标的悬挂引用,当一个目标被删除时,让它通知它的观察者将对该目标的引用复位。

5在发出通知前确保目标的状态自身是一致的

6 显式的指定兴趣的改变。 可以扩展注册的接口,让各观察者注册为仅对特定事件感兴趣,以提高更新效率

7如果目标和观察者之间的依赖关系特别复杂,需要一个ChangeManager

来维护,可以有Mediator中介者来实现。

 

 

The sample code is as below:

 

Observer.h

  1. #include <list>
  2. #include <iterator>
  3. #include <iostream>
  4. using namespace std;
  5. class Subject;
  6. class Observer
  7. {
  8. public:
  9.     virtual ~Observer(){cout<<"An observer is destoryed"<<endl;}
  10.     virtual void Update(Subject* theChangedSubject) = 0;
  11. protected:
  12.     Observer() {cout<<"An observer is created"<<endl;}
  13. };
  14. class Subject
  15. {
  16. public:
  17.     virtual ~Subject() {cout<<"A subjct is destroyed"<<endl; }
  18.     virtual void Attach(Observer*);
  19.     virtual void Detach(Observer*);
  20.     virtual void Notify();
  21. protected:
  22.     Subject() {cout<<"A subjct is created"<<endl;}
  23. private:
  24.     list<Observer*> _observers;
  25. };
  26. class ClockTimer:public Subject
  27. {
  28. public:
  29.     ClockTimer(){cout<<"A clock timer is created"<<endl;}
  30.     void Tick() {Notify();}
  31. };
  32. class DigitalClock: public Observer
  33. {
  34. public:
  35.     DigitalClock(ClockTimer* s);
  36.     virtual ~DigitalClock();
  37.     virtual void Update(Subject *);
  38.     virtual void Draw();
  39. private:
  40.     ClockTimer* _subject;
  41. };
  42. class AnalogClock: public Observer
  43. {
  44. public:
  45.     AnalogClock(ClockTimer* s);
  46.     virtual ~AnalogClock();
  47.     virtual void Update(Subject *);
  48.     virtual void Draw();
  49. private:
  50.     ClockTimer* _subject;
  51. };

Observer.cpp

  1. #include <list>
  2. #include <iostream>
  3. using namespace std;
  4. #include "Observer.h"
  5. void Observer::Update(Subject * theChangedSubject)
  6. {
  7.     cout<<"The Subject is changed"<<endl;
  8. }
  9. void Subject::Attach(Observer* o)
  10. {
  11.     //_observers->push_back(o);
  12.     _observers.push_back(o);
  13.     
  14. }
  15. void Subject::Detach(Observer* o)
  16. {
  17.     //_observers->remove(o);
  18.     _observers.remove(o);
  19. }
  20. void Subject::Notify()
  21. {
  22.     for(list<Observer*>::iterator ixx= _observers.begin(); ixx != _observers.end();++ixx) 
  23.     {
  24.       (*ixx)->Update(this);
  25.       
  26.     }
  27. }
  28. DigitalClock::DigitalClock(ClockTimer* s)
  29. {
  30.     _subject = s;
  31.     _subject->Attach(this);
  32. }
  33. DigitalClock::~DigitalClock()
  34. {
  35.     _subject->Detach(this);
  36. }
  37. void DigitalClock::Update(Subject* theChangedSubject)
  38. {
  39.     if (theChangedSubject == _subject)
  40.     {
  41.         Draw();
  42.     }
  43. }
  44. void DigitalClock::Draw()
  45. {
  46.     cout<<"Draw the time in Digital Clock"<<endl;
  47. }
  48. AnalogClock::AnalogClock(ClockTimer* s)
  49. {
  50.     _subject = s;
  51.     _subject->Attach(this);
  52. }
  53. AnalogClock::~AnalogClock()
  54. {
  55.     _subject->Detach(this);
  56. }
  57. void AnalogClock::Update(Subject* theChangedSubject)
  58. {
  59.     if (theChangedSubject == _subject)
  60.     {
  61.         Draw();
  62.     }
  63. }
  64. void AnalogClock::Draw()
  65. {
  66.     cout<<"Draw the time in Analog Clock"<<endl;
  67. }

 

main.cpp

  1. #include<iostream>
  2. #include "Observer.h"
  3. using namespace std;
  4. int main()
  5. {
  6.     ClockTimer* timer = new ClockTimer();
  7.     AnalogClock* analogClock = new AnalogClock(timer);
  8.     DigitalClock* digitalClock = new DigitalClock(timer);
  9.     timer->Notify();
  10.     return 0;
  11. }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值