设计模式之观察者模式

一、结构示意图

 

二、推模型和拉模型

 2.1 定义

2.2 区别

三、使用场景

四、代码

#include <iostream>
#include <list>

using namespace std;

class Subject;

class Observer
{
public:
    Observer(){}
    virtual ~Observer(){}
    virtual void update(Subject *subject) = 0;
    virtual void update(string content) = 0;
};


class  Subject
{
public:
    Subject() {}
    virtual ~ Subject() {}
    virtual string getContent() = 0;
    virtual string getAbstractContent() = 0;
    virtual void setContent(string content) = 0;
    // 订阅主题
    void attach(Observer *observer) {
        observers.push_back(observer);
    }
    // 取消订阅
    void detach(Observer *observer) {
        observers.remove(observer);
    }

    // 通知所有的订阅者
    virtual void notifyObservers() {
        for(Observer *reader: observers) {
            // 拉模型  (也是有推送的性质,只是粒度小一些)
            reader->update(this);
        }
    }
    // 通知所有的订阅者
    virtual void notifyObservers(string content) {
        for(Observer *reader: observers) {
            // 推模型
            reader->update(content);
        }
    }
private:
    list<Observer *> observers;    // 保存注册的观察者
};

class Reader : public Observer
{
public:
    Reader() {}
    virtual ~Reader() {}
    virtual void update(Subject *subject) {
        // 调用对应的方法去拉取内容 subject->getContent()
        cout << m_name << "收到报纸和阅读它, 具体内容" << subject->getContent() << endl;
    }
    virtual void update(string content) {
        // 推模型
        cout << m_name << "收到报纸和阅读它, 具体内容" << content << endl;
    }
    string getName() {
        return m_name;
    }
    void setName(string name) {
        m_name = name;
    }
private:
    string m_name;
};


class NewsPaper: public Subject
{
public:
    NewsPaper() {}
    virtual ~NewsPaper() {}

    void setContent(string content) {
        m_content = content;
        notifyObservers();
    }
    virtual string getContent() {
        return m_content;
    }
    virtual string getAbstractContent() {
        return  "摘要:";
    }
private:
    string m_content;
};


int main()
{
    // 创建一个报纸主题
    NewsPaper *subject = new NewsPaper();

    // 创建观察者,读者
    Reader *reader1 = new Reader();
    reader1->setName("张三");

    Reader *reader2 = new Reader();
    reader2->setName("李四");

    Reader *reader3 = new Reader();
    reader3->setName("王五");

    subject->attach(reader1);
    subject->setContent("今天下大雨了!");
    cout << "-----------------------" << endl;
    subject->attach(reader2);
    subject->attach(reader3);

    subject->setContent("今天大晴天");

    cout << "Hello World!" << endl;
    return 0;
}

摘抄自研磨设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值