观察者模式(行为型)

观察者模式(行为型)

一、目的

  系统中相互协作的模块之间常会有一个副作用:维护对象之间的一致性而导致对象间的紧耦合。
  为解决这个问题,需要定义一种一对多的依赖关系,当一个对象发生变化时,所有依赖它的对象都得到通知,并自动执行相关操作。由此可知,观察者模式是一个发布-订阅式模型。被依赖的对象为发布者,对它依赖的对象订阅它的变化用于后续做出反应。

二、应用场景

1)一个抽象模型有两个方面,其中一个方面依赖于另一个方面,需要将其二者封装进不同对象,且独立的变化和复用;
2)一个对象的改变需要告知其它对象,但是不知道需要告知多少对象;
3)一个对象的改变需要告知其它对象,但是不知道是那种对象(松耦合)。

三、组成

  1. 事件
      需求:同时向多个管着这发布状态变化;
      功能:提供添加、删除观察者对象的接口;
  2. 观察者
      为向自身发布状态变化的对象提供一个统一的反馈接口;
  3. 具体事件
      保存具体的事件;
      向他的观察者发送变化;
  4. 具体观察者
      泛化反应函数,做出具体反应;

四、牛刀小试

1)既定场景

  模拟在雨天和晴天里,人和蚂蚁的反应。

人物场景动作
晴天去钓鱼
雨天最好有伞再出门
蚂蚁晴天出去找吃的
蚂蚁雨天找材料保护蚁洞

2)show you the code

1)observer.h

#include <iostream>
#include <string>
#include <vector>
#include <set>

#ifndef _OBSERVER_H_
#define _OBSERVER_H_

class Event;
class Rain;
class Sunny;

enum EventType{
    E_RAINS = 1,
    E_SUNNY = 2
};
//Observer
class Observer{
public:
    virtual ~Observer();
public:
    //offer a single interface to react for the changes conveyed from the event
    virtual void Update(EventType);
};
//Concrete Observer:People
class People : public Observer{
public:
    People();
    ~People();
public:
    //Override the react interface to deal the concreate event
    void Update(EventType);
};
//Concrete Observer: Ant
class Ant : public Observer{
public:
    Ant();
    ~Ant();
public:
    void Update(EventType);
};
//Event
class Event{
public:
    Event(EventType);
    virtual ~Event();
public:
    //send status changes to observers
    virtual void Notify();
    //take base class pointer type as parameter for loose coupling
    virtual void Attach(Observer *);
    virtual void Detach(Observer *);
private:
    EventType m_type;
    //decoupling the observers' class and amount
    std::vector<Observer*> *m_observers;
};
//Concrete event:rain
class Rain : public Event{
public:
    Rain(EventType type);
    ~Rain();
public:
    void Rains();
};

class Sunny : public Event{
public:
    Sunny(EventType type);
    ~Sunny();
public:
    void Shine();
};

#endif

2)observer.cpp

#include "observer.h"

//**********************************Observers***********************************
Observer::~Observer(){}

void Observer::Update(EventType type)
{
    
}
//-------------------------------------------------------------------------------
People::People(){}

People::~People(){}

void People::Update(EventType type)
{
    switch (type)
    {
        case E_RAINS:
            std::cout << "It rains, I'd better not go out, unless having an umbrella." << std::endl;
            break;
        case E_SUNNY:
            std::cout << "It gets sunny, going to fishing may be a good idea. " << std::endl;
            break;
        default:
            break;
    }
}
//---------------------------------------------------------------------------------
Ant::Ant(){}

Ant::~Ant(){}

void Ant::Update(EventType type)
{
    switch (type)
    {
    case E_RAINS:
        std::cout << "It rains, get some material to protect my hole. " << std::endl;
        break;
    case E_SUNNY:
        std::cout << "It gets sunny, it's time to hang out and search something to eat. " << std::endl;
        break;
    default:
        break;
    }
}

//********************************Event***************************************
Event::Event(EventType type)
{
    m_observers = new std::vector<Observer*>;
    m_type = type;
}

Event::~Event()
{
    delete m_observers;
}

void Event::Notify()
{
    for(std::vector<Observer*>::iterator it = m_observers->begin(); it != m_observers->end(); ++it)
    {
        (*it)->Update(m_type);
    }
}

void Event::Attach(Observer *observer)
{
    m_observers->push_back(observer);
}

void Event::Detach(Observer* observer)
{
    m_observers->pop_back();
}
//---------------------------------------------------------------------------------------
Rain::Rain(EventType type):Event(type){}

Rain::~Rain(){}

void Rain::Rains()
{
    std::cout << "I am rain, and I am going to rain. " << std::endl;
    Notify();
}
//---------------------------------------------------------------------------------------
Sunny::Sunny(EventType type):Event(type){}

Sunny::~Sunny(){}

void Sunny::Shine()
{
    std::cout << "I am sunny day, and I am going to shine you. " << std::endl;
    Notify();
}

3)main.cpp

#include <unistd.h>
#include "observer.h"

int main(int argc, char **argv)
{
    Ant ant;
    People people;

    Rain rain(E_RAINS);
    Sunny sunny(E_SUNNY);

    rain.Attach(&ant);
    rain.Attach(&people);

    sunny.Attach(&ant);
    sunny.Attach(&people);

    sleep(3);
    rain.Rains();
    sleep(3);
    sunny.Shine();

    return 0;
}

4)makefile

all:
	g++ -I. observer.cpp main.cpp -o observer.out
.PHONY:clean
clean:
	rm -f observer.out

五、说明

  代码结构不符合开发规范,仅作为对模式的理解与练习。欢迎在评论区发表见解,共同进步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值