设计模式之观察者模式

一、模式动机

  建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。

二、模式定义

  观察者模式(Observer Pattern)定义了对象之间的一对多依赖,这样一来,当一个对象改变状态是,它的所有依赖者都会收到通知并自动更新。
这里写图片描述

观察者模式四个角色:

  • Subject:抽象主题

  • ConcreteSubject:具体目标

  • Observer:观察者
  • ConcreteObsever:具体观察者

这里写图片描述

三、模式示例

  一个气象站当温度变化时,通知一些气象布告板。气象台就是主题对象,气象布告板则是观察者们。
目前我们设置三个气象布告板:目前状况、气象统计和天气预报。用户可以随心所欲得添加或删除任何布告板。

这里写图片描述

C++代码实现

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

class Observer
{
public:
    virtual void update() = 0;
};

class GeneralDisplay : public Observer
{
public:
    void update(){ cout << "目前状况" << endl; }
};

class StatisticsDisplay : public Observer
{
public:
    void update(){ cout << "气象统计" << endl; }
};

class ForeCastDisplay : public Observer
{
public:
    void update(){ cout << "天气预报" << endl; }
};

class Subject
{
public:
    void registerObserver(Observer * observer)
    {    
        observers.push_back(observer);
    }
    void removeObserver(Observer * observer)
    {
        for (vector<Observer*>::iterator iter = observers.begin();
            iter != observers.end(); iter++)
        {
            if (*iter ==  observer)
            {
                observers.erase(iter);
                return;
            }
        }
    }
    void notifyObserver()
    {
        for (vector<Observer*>::iterator iter = observers.begin();
            iter != observers.end(); iter++)
        {
            (*iter)->update();
        }
    }

protected:
    vector<Observer*> observers;
};

class WeatherData : public Subject
{
private:
    float temperature;
    float humidity;
    float pressure;
};

int _tmain(int argc, _TCHAR* argv[])
{
    Subject* weatherData = new  WeatherData();
    Observer* generalDisplay = new GeneralDisplay();
    Observer* statisticsDisplay = new StatisticsDisplay();
    Observer* foreCastDisplay = new ForeCastDisplay();
    weatherData->registerObserver(generalDisplay);
    weatherData->registerObserver(statisticsDisplay);
    weatherData->registerObserver(foreCastDisplay);
    weatherData->notifyObserver();

    delete generalDisplay;
    delete statisticsDisplay;
    delete foreCastDisplay;
    delete weatherData;
    system("pause");
    return 0;
}

运行结果:

这里写图片描述

四、分析总结

  观察者模式中关键对象是观察目标和观察者,一个目标可以有任意数目的与之相依赖的观察者,一旦目标的状态发生改变,所有的观察者都将得到通知。观察者模式让主题和观察者之间送耦合,改变主题或者观察者的任何一方都不会影响另外一方。
  MVC模式是一种架构模式,它包含三个角色:模型(Model),视图(View)和控制器(Controller)。观察者模式可以用来实现MVC模式,观察者模式中的观察目标就是MVC模式中的模型(Model),而观察者就是MVC中的视图(View),控制器(Controller)充当两者之间的中介者(Mediator)。当模型层的数据发生改变时,视图层将自动改变其显示内容。

优点

  1. 观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
  2. 观察者模式在观察目标和观察者之间建立一个抽象的耦合。
  3. 观察者模式支持广播通信。
  4. 观察者模式符合“开闭原则”的要求。

缺点

  1. 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值