Observer,观察者模式,C++描述

时间:2023-03-09 20:43:45
Observer,观察者模式,C++描述

body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

常见设计模式的解析和实现(C++)之十五-Observer模式  
作用:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.
Observer,观察者模式,C++描述
解析:
Observer 模式定义的是一种一对多的关系,这里的一就是图中的 Subject 类,而多则是 Obesrver 类,当 Subject 类的状态发生变化的时候通知与之对应的 Obesrver 类们也去相应的更新状态,同时支持动态的添加和删除 Observer 对象的功能.Obesrver 模式的实现要点是,第一一般 subject 类都是采用链表等容器来存放 Observer 对象,第二抽取出 Observer 对象的一些公共的属性形成 Observer 基类,而 Subject 中保存的则是 Observer 类对象的指针,这样就使 Subject 和具体的 Observer 实现了解耦,也就是 Subject 不需要去关心到底是哪个Observer对放进了自己的容器中.生活中有很多例子可以看做是 Observer 模式的运用,比方说,一个班有一个班主任(Subject),他管理手下的一帮学生(Observer),当班里有一些事情发生需要通知学生的时候,班主任要做的不是逐个学生挨个的通知而是把学生召集起来一起通知,实现了班主任和具体学生的关系解耦.
#ifndef __OBSERVE_H__
#define __OBSERVE_H__
#include<iostream>
#include<list>
typedef int state;
using namespace std;
class Observer;
class Subject
{
        public:
                Subject():_subjectState(-1){}
                virtual ~Subject();  // 这边要删除开辟的空间
                void attach(Observer*);
                void detach(Observer*);
                void notify();
                virtual int getState();
                virtual void setState(state);
        protected:
                state _subjectState;
                list<Observer*> _observerList;
};
class ConcreteSubject:public Subject
{
        public:
                ConcreteSubject(){}
                int getState();
                void setState(state);
                virtual ~ConcreteSubject(){}
};
class Observer
{
        public:
                Observer():_obState(-1){}
                virtual void update(Subject*) = 0;
                virtual ~Observer(){}
        protected:
                state _obState;
};
class ConcreteObserver:public Observer
{
        public:
                ConcreteObserver(){}
                void update(Subject*);
                ~ConcreteObserver(){}
};
#endif
#include"observer.h"
#include<algorithm>
#include<iterator>
#include<iostream>
using namespace std;
Subject::~Subject()
{
        cout<<"~Subject()"<<endl;
        list<Observer*>::iterator it = _observerList.begin();
        for(;it!=_observerList.end();++it)
        {
                delete *it;
        }
        _observerList.clear();
}
void Subject::attach(Observer* pObs)
{
        if(NULL!=pObs)
                _observerList.push_back(pObs);
}
void Subject::detach(Observer* pObs)
{
        list<Observer*>::iterator it = find(_observerList.begin(),_observerList.end(),pObs);
        if(it!=_observerList.end())
                _observerList.erase(it);
}
void Subject::notify()
{
        list<Observer*>::iterator it = _observerList.begin();
        for(;it!=_observerList.end();++it)
                //(*(*it)).update(this); // 这里必须要两个括号,*(*it).update(this);  是错的
                (*it)->update(this);
//        for(auto& it:_observerList) // 不知道为什么在这里不行啊,说是C++11不让声明没有类型的变量
//                it->update(this);
}
int Subject::getState()
{
        return _subjectState;
}
void Subject::setState(state newState)
{
        _subjectState = newState;
}
/*   ConcreteSubject   */
int ConcreteSubject::getState()
{
        return _subjectState;  // 要访问这个,基类就不能是私有成员,重新设置成保护
}
void ConcreteSubject::setState(state newState)
{
        _subjectState = newState;
}
/*   Observer   */
//直接传消息,叫推模式 string = ""
//传指针,    叫拉模式
void ConcreteObserver::update(Subject* pSub)
{
        if(_obState!=pSub->getState())
        {
                _obState = pSub->getState();
                cout<<"update state,Observer state now is "<<_obState<<endl;
        }
}
#include<iostream>
#include"observer.h"
using namespace std;
int main()
{
        Observer* p1 = new ConcreteObserver;
        Observer* p2 = new ConcreteObserver;
        Subject* p = new ConcreteSubject;
        p->attach(p1);
        p->attach(p2);
        p->setState(5);
        p->notify();  // subject对象通知所有observer对象
        p->detach(p1);
        p->setState(10);
        p->notify();
        delete p;
        return 0;
}
Observer,观察者模式,C++描述Observer,观察者模式,C++描述