`

[行为模式]head first 设计模式之观察者模式(observer)

 
阅读更多
1 定义:
    观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。
    定义对象间的一种一对多的以来关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    别名:依赖(Dependennts),发布-订阅(Publish-Subscribe)


2 设计原则
  为了交互对象之间的松耦合设计而努力,简单点讲就是出版者+订阅者=观察者模式。

3 参与类别
    参与本模式的各类别列出如下。成员函式以模拟的方式列出。
   3.1 抽象目标类别
    此抽象类别提供一个接口让观察者进行添附与解附作业。此类别内有个不公开的观察者串炼,并透过下列函式(方法)进行作业
    添附(Attach):新增观察者到串炼内,以追踪目标物件的变化。
    解附(Detach):将已经存在的观察者从串炼中移除。
    通知(Notify):利用观察者所提供的更新函式来通知此目标已经产生变化。
添附函式包涵了一个观察者物件参数。也许是观察者类别的虚拟函式(即更新函式),或是在非面向对象的设定中所使用的函式指标(更广泛来讲,函式子或是函式物件)。

    3.2 目标类别
    此类别提供了观察者欲追踪的状态。也利用其源类别(例如前述的抽象目标类别)所提供的方法,来通知所有的观察者其状态已经更新。此类别拥有以下函式
取得状态(GetState):回传该目标物件的状态。

    3.3 抽象观察者接口
    抽象观察者类别是一个必须被实做的抽象类别。这个类别定义了所有观察者都拥有的更新用接口,此接口是用来接收目标类别所发出的更新通知。此类别含有以下函式
更新(Update):会被实做的一个抽象(虚拟)函式。

    3.4 观察者类别
    这个类别含有指向目标类别的参考(reference),以接收来自目标类别的更新状态。此类别含有以下函式
    更新(Update):是前述抽象函式的实做。当这个函式被目标物件呼叫时,观察者物件将会呼叫目标物件的取得状态函式,来其所拥有的更新目标物件资讯。
每个观察者类别都要实做它自己的更新函式,以应对状态更新的情形。
当目标物件改变时,会通过呼叫它自己的通知函式来将通知送给每一个观察者物件,这个通知函式则会去呼叫已经添附在串炼内的观察者更新函式。通知与更新函式可能会有一些参数,好指明是目前目标物件内的何种改变。这么作将可增进观察者的效率(只更新那些改变部份的状态)。

4 观察者模式的优点
    观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的,这样,对于两者来说都比较容易进行扩展。
    观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。但同时,这也算是观察者模式一个缺点,由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。并且,在链式结构中,比较容易出现循环引用的错误,造成系统假死。




#ifndef   OBSERVER_H
#define   OBSERVER_H

#include <iostream>
#include <list>
using namespace std;

//观察者模式
namespace Observer
{

//////////////////////////////////////////////////////////////////////////
class Observer
{
public:
    virtual void update(float temp, float humidity, float pressure) = 0;
};
//////////////////////////////////////////////////////////////////////////
typedef list<Observer*> ObserverList;

class Subject
{
public:
    virtual void registerObserver(Observer* ob) = 0 ;
    virtual void removeObserver(Observer* ob) = 0;
    virtual void notifyObserver() = 0;
};

class WeatherData : public Subject
{
public:
    virtual void registerObserver(Observer* ob)
    {
        m_ObserverList.push_back(ob);
    }

    virtual void removeObserver(Observer* ob)
    {
        ObserverList::const_iterator itr = find(ob);
        if ( itr != m_ObserverList.end() )
        {
            m_ObserverList.erase(itr);
        }
    }

    virtual void notifyObserver()
    {
        ObserverList::const_iterator itr = m_ObserverList.begin();
        ObserverList::const_iterator end = m_ObserverList.end();
        for ( ; itr != end; ++itr)
        {
            if ( *itr != NULL)
            {
                (*itr)->update(m_Tempperature, m_Humidity, m_Pressure);
            }
        }
    }

    void measurementsChanged()
    {
        notifyObserver();
    }

    void setMeasurements(float tempperature, float humidity, float pressure)
    {
        this->m_Tempperature = tempperature;
        this->m_Humidity     = humidity;
        this->m_Pressure     = pressure;
        measurementsChanged();
    }

private:
    ObserverList::const_iterator find( const Observer* ob)
    {
        ObserverList::const_iterator itr = m_ObserverList.begin();
        ObserverList::const_iterator end = m_ObserverList.end();
        for ( ; itr != end; ++itr)
        {
            if ( *itr == ob)
            {
                return itr;
            }
        }

        return end;
    }

private:
    ObserverList m_ObserverList;
    float        m_Tempperature;
    float        m_Humidity;
    float        m_Pressure;
};

//////////////////////////////////////////////////////////////////////////
class DisplayElement
{
public:
    virtual void display() = 0 ;
};

//////////////////////////////////////////////////////////////////////////
class CurrentConditionDisplay : public Observer, public DisplayElement
{
public:
    CurrentConditionDisplay(Subject* weatherData)
        : m_Humidity(0),
        m_Tempperature(0.0f),
        m_WeatherData(NULL)
    {
        if (weatherData != NULL)
        {
            if (m_WeatherData!=NULL)
            {
                delete m_WeatherData;
                m_WeatherData = NULL;
            }

            this->m_WeatherData = weatherData;
            this->m_WeatherData->registerObserver(this);
        }
    }
    virtual ~CurrentConditionDisplay()
    {
        if (m_WeatherData != NULL)
        {
            delete m_WeatherData;
            m_WeatherData = NULL;
        }
    }
    virtual void update(float temp, float humidity, float pressure)
    {
        this->m_Tempperature = temp;
        this->m_Humidity     = humidity;
        display();
    }

    virtual void display()
    {
        cout << "Current conditions: " << m_Tempperature << "F degree and " << m_Humidity << "% humidity" <<endl;
    }

private:
    float     m_Tempperature;
    float     m_Humidity;
    Subject*  m_WeatherData;
};

class WeatherStation
{
public:
    void run()
    {
        WeatherData* weatherData = new WeatherData();

        CurrentConditionDisplay* currentDisplay1 = new CurrentConditionDisplay(weatherData);
        CurrentConditionDisplay* currentDisplay2 = new CurrentConditionDisplay(weatherData);
        CurrentConditionDisplay* currentDisplay3 = new CurrentConditionDisplay(weatherData);
        //StatisticsDisplay* statisticsDisplay    = new StatisticsDisplay(weatherData);
        //ForecastDisplay* forecastDisplay    = new ForecastDisplay(weatherData);

        weatherData->setMeasurements(80, 65, 30.4f);
        weatherData->setMeasurements(82, 70, 29.2f);
        weatherData->setMeasurements(78, 90, 29.2f);

        if (weatherData != NULL)
        {
            delete weatherData;
        }

        if (currentDisplay1 != NULL)
        {
            delete currentDisplay1;
        }

        if (currentDisplay2 != NULL)
        {
            delete currentDisplay2;
        }

        if (currentDisplay3 != NULL)
        {
            delete currentDisplay3;
        }
    }
};

}//namespace Observer

#endif
分享到:
评论

相关推荐

    《HeadFirst设计模式》观察者模式c++实现代码

    观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 Observer Pattern defines a one-to-many dependency between objects so that when one object ...

    Head.First设计模式_PDF.part1

    Head.First设计模式_PDF(高清扫描版) 第一部分(共三部分) 在我的资源下可找到其他两部部分 强大的写作阵容。《Head First设计模式》作者Eric Freeman和ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁...

    OBserver模式设计实现

    Head First模式设计用的是Java,实现观察者模式使用C++

    OOPractice:《HeadFirst 设计模式》中主要模式的具体实现

    OOPractice 设计模式项目练习 目录 第一章 模拟鸭子的行为 duck 第二章 观察者模式 observer 第三章 装饰着模式 decorater 第四章 工厂模式 factory 第五章 封装调用 methodinvocation ...《Head First 设计模式》

    headfirst_observer_subject.zip_单片机开发_Java_

    设计模式观察者模式

    java实验:设计模式2.doc

    java实验: 设计模式(单子、工厂、策略、组合、观察者模式)练习 在上次作业基础上,设计一个贩卖各类书籍的电子商务网站的购物车系统。该系统包括 的模块有: 模块1:图书目录的添加模块,实现对书本信息的增加。 ...

    DesignPattern

    这个工程是《Head First设计模式》书本里面涉及到的例程代码源码 ##1.Strategy(策略模式) 策略设计模式就是定义算法族(接口中定义的方法&lt;也就是对象的行为&gt;),分别进行封装(接口实现类),让他们之间可以相互...

    asp.net知识库

    动态控制Page页的Head信息 SubmitOncePage:解决刷新页面造成的数据重复提交问题 SharpRewriter:javascript + xml技术利用#实现url重定向 采用XHTML和CSS设计可重用可换肤的WEB站点 asp.net的网址重定向方法的比较...

    P2P-chat:此 P2P 聊天已实现为群聊。 单例模式、观察者模式和 MVC 模式

    #P2P 聊天 此 P2P 聊天已实现为群聊。 聊天是这样实现的: 您必须首先在同一本地服务器中使用聊天。 适应更广泛的方法并不难。 尽管如此,由于测试问题,我... ##Bibliography Head First 设计模式 - O'Reilly Media

    java餐饮管理系统源码6-design-patterns:设计模式

    观察者模式定义了对象之间一对多的依赖, 这样一来, 当一个对象改变状态 所有依赖都会收到通知, 自动更新 :beer_mug:设计原则1: 为了交互对象之间的松耦合设计而努力 :star:实现细节 自己设计的Observer/Subject: 见 ...

    ObserverDemo

    用C++写的一个观察者模式的小Demo,思想来源于Head First

    design_patterns

    patterns(设计模式)Design Patterns In PythonDesign Patterns Introduction(设计模式介绍)Strategy Pattern(策略模式)实现:design_patterns/strategy.py示例:examples/strategy_example.pyObserver Pattern...

Global site tag (gtag.js) - Google Analytics