Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12838707
  • 博文数量: 1293
  • 博客积分: 13501
  • 博客等级: 上将
  • 技术积分: 17974
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-08 18:11
文章分类

全部博文(1293)

文章存档

2019年(1)

2018年(1)

2016年(118)

2015年(257)

2014年(128)

2013年(222)

2012年(229)

2011年(337)

分类:

2013-01-08 09:55:43

原文地址:设计模式之观察者模式 作者:lubing521

     去年《步步惊心》穿越连续剧可谓火了一下,里面的人物 太监李德全,侍女 马尔泰.若曦在伺候皇上的时候可谓用心良苦,他们可谓察言观色,谨言慎行。不然早混不下去了,为此做为观察者身份出现的他俩很能察觉到皇上的举动代表什么一下,套用设计模式来说,就是一种状态变更了,其他都能及时了解到其状态的情况,比如皇上示意用茶,用膳他俩就必须知道,不然就挨板子了。
    为实现上面的功能,定义以下类。


点击(此处)折叠或打开

  1. class observer{
  2. public:
  3.     virtual ~observer();
  4.     virtual void update(subject *psub)=0;
  5.     virtual void printinfo()=0;
  6. protected:
  7.     observer();
  8.     state _st;
  9. private:

  10. };

  11. class observer_ruoxi:public observer{//马尔泰.若曦
  12. public :
  13.     virtual subject *getsubject();
  14.     observer_ruoxi(subject* psub);
  15.     virtual ~observer_ruoxi();
  16.     void update(subject *psub);
  17.     void printinfo();
  18. private:
  19.     subject *_psub;

  20. };

  21. class observer_lidequan:public observer{//太监李德全
  22. public :
  23.     virtual subject *getsubject();
  24.     observer_lidequan(subject* psub);
  25.     virtual ~observer_lidequan();
  26.     void update(subject *psub);
  27.     void printinfo();
  28. private:
  29.     subject *_psub;

  30. };
其中用到了前置声明,当出现以下情况时,使用前置声明
class subject;来解决互用问题
class observer{
//此处用到subject 类
};
class subject {
       //此处用到了observer类
};


点击(此处)折叠或打开

  1. class observer;//类的前置声明

  2. class subject{//被观察者 皇上
  3. public :
  4.     virtual ~subject();
  5.     virtual void attach(observer* pobv);
  6.     virtual void detach(observer* pobv );
  7.     virtual void notify();
  8.     virtual void set_state(const state &st)=0;//const 表明入参是不可被修改的
  9.     virtual state getstate()=0;
  10. protected:
  11.     subject();
  12. private:
  13.     list<observer*>*_pobvs;//使用list维护观察者

  14. };
在被观察者上,用到了list容器来维护整个观察者。使用subject::notify()来遍历整个观察者,以通知到被观察者状态的变更。

下面是各个类的功能实现

点击(此处)折叠或打开

  1. //被观察者subject.cpp

  2. /*
  3.  * subject.cpp
  4.  *
  5.  * Created on: Nov 27, 2012
  6.  * Author: root
  7.  */

  8. #include "subject.h"
  9. #include <iostream>
  10. #include <list>

  11. subject::subject(){
  12.     _pobvs=new list<observer*>;

  13. }

  14. subject::~subject(){


  15. }

  16. void subject::attach(observer *pobv){
  17.     _pobvs->push_front(pobv);
  18. }

  19. void subject::detach(observer*pobv){
  20.     if(pobv != NULL)
  21.         _pobvs->remove(pobv);
  22. }

  23. void subject::notify(){
  24.     list<observer*>::iterator it;
  25.     it=_pobvs->begin();
  26.     for(;it!=_pobvs->end();it++){
  27.         (*it)->update(this);

  28.     }

  29. }

  30. concretesubject::concretesubject(){

  31.     _st='\0';

  32. }

  33. concretesubject::~concretesubject(){


  34. }

  35. state concretesubject::getstate(){
  36.     return _st;

  37. }

  38. void concretesubject::set_state(const state & st){

  39.     _st=st;

  40. }


点击(此处)折叠或打开

  1. //观察者类的实现observer.cpp
  2. /*
  3. * observer.cpp
  4. *
  5. * Created on: Nov 27, 2012
  6. * Author: root
  7. */
  8. #include "observer.h"
  9. #include
  10. using namespace std;
  11. observer::observer(){
  12. _st='\0';
  13. }
  14. observer::~observer(){
  15. //do nothing
  16. }
  17. observer_ruoxi::observer_ruoxi(subject *psub){
  18. _psub=psub;
  19. _psub->attach(this);
  20. }
  21. observer_ruoxi::~observer_ruoxi(){
  22. _psub->detach(this);
  23. if(_psub !=0)
  24. delete _psub;
  25. }
  26. void observer_ruoxi::printinfo(){
  27. cout<<"若曦获悉皇上: "<<_psub->getstate()<
  28. }
  29. void observer_ruoxi::update(subject* psub){
  30. _st=psub->getstate();
  31. printinfo();
  32. }
  33. subject* observer_ruoxi::getsubject(){
  34. return _psub;//倘若由一个虚函数未写,比如此函数,即使不写也应该在类中加上函数体。这编译器会报错 undefined reference to `vtable for
  35. }
  36. observer_lidequan::observer_lidequan(subject *psub){
  37. _psub=psub;
  38. _psub->attach(this);
  39. }
  40. observer_lidequan::~observer_lidequan(){
  41. _psub->detach(this);
  42. if(_psub !=0)
  43. delete _psub;
  44. }
  45. void observer_lidequan::printinfo(){
  46. cout<<"李德全获悉皇上: "<<_psub->getstate()<
  47. }
  48. void observer_lidequan::update(subject* psub){
  49. _st=psub->getstate();
  50. printinfo();
  51. }
  52. subject* observer_lidequan::getsubject(){
  53. return _psub;
  54. }


点击(此处)折叠或打开

  1. /*
  2.  * main.cpp
  3.  *
  4.  * Created on: Nov 27, 2012
  5.  * Author: root
  6.  */

  7. #include "subject.h"
  8. #include "observer.h"
  9. #include <iostream>
  10. using namespace std;

  11. int main(int argc,char *argv[]){
  12.     concretesubject *sub= new concretesubject();
  13.     observer *ruoxi= new observer_ruoxi(sub);
  14.     observer *lidequan= new observer_lidequan(sub);

  15.     sub->set_state("喝茶");
  16.     sub->notify();
  17.     sub->set_state("用膳");
  18.     sub->notify();

  19.     return 0;
  20. }
 observer.zip   

阅读(1428) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~