当前位置:编程学习 > C/C++ >>

设计模式C++描述----04.观察者(Observer)模式

一. 概述

Observer 模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变。

 \

Sbuject 相当于通知者,它提供依赖于它的观察者Observer 的注册(Attach)和注销(Detach)操作,并且提供了使得依赖于它的所有观察者同步的操作(Notify)。


Observer 相当于观察者,则提供一个Update操作,注意这里的 Observer 的 Update 操作并不在Observer 改变了Subject目标状态的时候就对自己进行更新,这个更新操作要延迟到 Subject 对象发出 Notify 通知所有 Observer 进行修改(调用Update)。


二. 举例

最常见的一个例子就是:对同一组数据进行统计分析时候,我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变。

结构关系图如下:

 \


DataSubject : 我们就认为是原始数据。

SheetObserver:就认为是表格,用来显示原始数据用的。

ChartObserver :就认为是图表,也是来显示原始数据的。


代码如下:

 

[cpp]  //////////////////////////////////////////////////////////////////////////  
//观察者基类  
class Observer 

public: 
    virtual ~Observer() 
    { 
    } 
 
    virtual void Update(Subject* sub) = 0; 
    virtual void PrintInfo() = 0; 
     
protected: 
    Observer() 
    { 
        _st = '\0'; 
    } 
     
    string _st; 
}; 
 
//////////////////////////////////////////////////////////////////////////    
//通知者基类    
class Subject 

public: 
    virtual ~Subject() 
    { 
    } 
     
    //注册观察者,这样通知者就能通知到观察者  
    virtual void Attach(Observer* obv) 
    { 
        _obvs->push_front(obv); 
    } 
     
    //注销观察者,通知者不再通知观察者  
    virtual void Detach(Observer* obv) 
    { 
        if (obv != NULL) 
            _obvs->remove(obv); 
    } 
     
    //通知操作,通知后对于每个注册过的观察者,将会调用自己的update方法  
    virtual void Notify() 
    { 
        list<Observer*>::iterator it; 
        it = _obvs->begin(); 
         
        for (;it != _obvs->end();it++) 
        { 
            (*it)->Update(this); 
        } 
    } 
     
    virtual void SetState(const string& st) = 0; 
    virtual string GetState() = 0; 
     
protected: 
    Subject() 
    { 
        _obvs = new list<Observer*>; 
    } 
     
private: 
    list<Observer* >* _obvs; 
}; 
 
//////////////////////////////////////////////////////////////////////////  
//具体的数据通知者  
class DataSubject:public Subject 

public: 
    DataSubject() 
    { 
        _st = '\0'; 
    } 
     
    ~DataSubject() 
    { 
    } 
     
        //自己的状态  
    string GetState() 
    { 
        return _st; 
    } 
     
    void SetState(const string& st) 
    { 
        _st = st; 
    } 
     
private: 
    string _st; 
}; 
 
//////////////////////////////////////////////////////////////////////////  
//数据表格观察者  
class SheetObserver:public Observer 

public: 
    virtual Subject* GetSubject() 
    { 
        return _sub; 
    } 
     
        //构造函数里,把自己注册到通知者里  
    SheetObserver(Subject* sub) 
    { 
        _sub = sub; 
        _sub->Attach(this); 
    } 
     
    virtual ~SheetObserver() 
    { 
        _sub->Detach(this); 
        if (_sub != 0) 
            delete _sub; 
    } 
     
    //更新操作  
    void Update(Subject* sub) 
    { 
        _st = sub->GetState(); //具体的数据可以从Subject这个通知者中取  
        PrintInfo(); 
    } 
     
    void PrintInfo() 
    { 
        cout<<"Sheet observer.... "<<_sub->GetState()<<endl; 
    } 
 
private: 
    Subject* _sub; 
}; 
 
//数据图表观察者  
class ChatObserver:public Observer 

public: 
    virtual Subject* GetSubject() 
    { 
      

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,