`

[行为模式]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 设计模式学习笔记2--观察者模式 demo

    总的来说,HeadFirst设计模式的学习笔记2关于观察者模式的演示,旨在帮助开发者理解如何使用观察者模式来构建可扩展的系统。通过实际的代码示例,我们可以更深入地掌握这一模式,并将其应用到日常开发中,提升代码的...

    Headfirst设计模式中文高清PDF+附书源码

    《Headfirst设计模式》是一本深受开发者欢迎的设计模式学习书籍,尤其对于初学者而言,其独特的教学方式使得复杂的概念变得易于理解。这本书以其高清的中文版PDF格式提供,结合书中源码,为读者提供了深入实践的可能...

    head first 设计模式 观察者模式 C++ 代码

    观察者模式(Observer Pattern)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式常用于实现事件驱动编程或者...

    Head First 之之观察者模式

    《Head First 之观察者模式》是一本深入浅出介绍观察者模式的书籍,通过生动有趣的方式帮助读者理解和掌握这一设计模式。观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生...

    [中文]Head-First设计模式.pdf

    《Head-First设计模式》是一本面向初学者的优秀设计模式教程,主要针对Java编程语言。...《Head-First设计模式》以其独特的教学方式,使得这些复杂的概念变得生动易懂,是每一位Java程序员进阶的必读之作。

    Head First设计模式和HeadFirst in java 源码以及23种设计模式关系图

    总的来说,这个压缩包包含的资源可以帮助你深入理解设计模式,通过《HeadFirst设计模式》和《HeadFirst in Java》的源码,你可以学习到如何在实际项目中应用这些模式。而UML类图则提供了直观的视角,便于你把握设计...

    HeadFirst设计模式PPT

    《HeadFirst设计模式》是一本深受开发者欢迎的书籍,它以独特、易理解的方式介绍了软件设计中的重要概念——设计模式。设计模式是经验丰富的开发者在解决常见问题时总结出的最佳实践,它们为软件设计提供了可复用的...

    HeadFirst设计模式英文版

    《Head First 设计模式》的英文版是一本面向初学者的设计模式入门书籍,它以幽默风趣的文风,深入浅出地介绍了软件设计中经常使用的设计模式。设计模式是一套被反复使用、多数人知晓、经过分类编目、代码设计经验的...

    Head First Design Patterns 英文版 Head First设计模式

    行为型模式如策略(Strategy)、观察者(Observer)、装饰器(Decorator)和模板方法(Template Method)等,则关注对象间的行为协作。 每章结束时,书中还包含了要点整理和习题,帮助读者复习和巩固知识点。通过...

    head first 设计模式 PDF电子书下载

    行为型模式则关注于对象间的交互和责任分配,例如策略模式(Strategy)、观察者模式(Observer)和命令模式(Command)。 在《Head First 设计模式》中,作者通过幽默风趣的插图和生动的例子,使得原本可能枯燥的...

    headfirst设计模式

    3. 行为型模式:如策略(Strategy)、模板方法(Template Method)、观察者(Observer)、迭代器(Iterator)、访问者(Visitor)、命令(Command)、责任链(Chain of Responsibility)、备忘录(Memento)、状态...

    HeadFirst设计模式源代码

    《HeadFirst设计模式源代码》是一本面向程序员的深度学习设计模式的书籍,它通过直观易懂的方式将复杂的概念转化为生动的图像和有趣的例子,帮助读者深入理解并掌握设计模式。设计模式是软件工程中的一种最佳实践,...

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

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

    HeadFirst设计模式JAVA版源码

    《HeadFirst设计模式JAVA版源码》是一份深入学习设计模式的重要资源,它基于流行的编程语言Java,旨在帮助开发者理解并应用设计模式于实际项目中。设计模式是软件工程中的重要概念,它代表了在特定场景下解决问题的...

    head first 设计模式 高清完整版 pdf

    《Head First设计模式》是一本深受开发者喜爱的经典书籍,它以独特、生动的方式讲解了设计模式这一核心的软件工程概念。设计模式是经验丰富的开发者在解决常见问题时总结出的最佳实践,它们为软件设计提供了可复用的...

    Head First 设计模式 源代码

    《Head First 设计模式》是一本非常受欢迎的软件设计书籍,它以易懂且生动的方式介绍了23种经典的GOF设计模式。这本书的源代码包含了书中所有示例的实现,对于学习和理解设计模式有着极大的帮助。源代码的下载使得...

    Head First设计模式官方原码

    3. **行为型模式**:包括策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、迭代器模式(Iterator)、命令模式(Command)、备忘录模式(Memento)、状态模式(State)、访问者模式...

Global site tag (gtag.js) - Google Analytics