观察者模式

一 应用场景
社交网络中,当我们关注的一个人发表状态后粉丝就会有通知。这就用到了观察者模式,即:当一个对象发生改变的时候,其他对象将相应的做出反应。

二 定义
观察者模式 Observer Pattern: 定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。
这里写图片描述
Subject 目标:被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察。提供注册和删除观察者对象的接口。同时定义notify的方法。可以是抽象类或者具体类。

ConcreteSubject具体目标:具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知。

Observer 观察者:观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。

ConcreteObserver具体观察者:在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。

观察者模式描述了如何建立对象与对象之间的依赖关系,以及如何构造满足这种需求的系统。观察者模式包含观察目标和观察者两类对象,一个目标可以有任意数目的与之相依赖的观察者,一旦观察目标的状态发生改变,所有的观察者都将得到通知。

三 C++实现
Blog.h

#pragma once 

#include <list>
#include <iterator>

#include "Observer.h"

using namespace std;


class Blog
{
public:
    Blog(){}

    virtual ~Blog(){}

    void Attach(Observer * _observer) {
        obs_list.push_back(_observer);
    }

    void Remove(Observer * _observer){
        obs_list.remove(_observer);
    }

    void Notify(){
        list<Observer *>::iterator iter = obs_list.begin();
        for(;iter!=obs_list.end();iter++){
            (*iter)->Update();
        }
    }

    virtual void setStatus(std::string _status){
        m_status = _status;
    }

    virtual std::string getStatus(){
        return m_status;
    }


private:
    std::list<Observer *> obs_list;

protected:
    std::string m_status;
};

Csdnblog.h

#pragma once 

#include <string>

#include "Blog.h"

using namespace std;

class CsdnBlog:public Blog
{
public:
    CsdnBlog(std::string _blog_name):blog_name(_blog_name){}

    virtual ~CsdnBlog(){}

    void setStatus(std::string _str){
        m_status = "csdn notify:" + blog_name + _str;
    }

    std::string getStatus(){
        return m_status;
    }

private:
    std::string blog_name;
};

Observer.h

#pragma once 


class Observer    
{  
public:  
    Observer() {}  
    virtual ~Observer() {}  
    virtual void Update() {}   
};  

BlogObserver.h

#pragma once 

#include <string>
#include <iostream>

#include "Observer.h"
#include "Blog.h"

using namespace std;

class BlogObserver : public Observer     
{  
public:
    BlogObserver(std::string _name, Blog * _blog):m_name(_name), m_blog(_blog){}

    void Update(){
        std::string status = m_blog->getStatus();
        std::cout << m_name << " --- " << status<< std::endl;
    }

private:
    std::string m_name;
    Blog * m_blog;
};

main.cpp

#include <iostream>

#include "Blog.h"
#include "CsdnBlog.h"
#include "BlogObserver.h"


using namespace std;


int main()
{
    Blog * blog = new CsdnBlog("C++");
    Observer * observer1 = new BlogObserver("ob1", blog);
    blog->Attach(observer1);
    blog->setStatus("publish a blog");
    blog->Notify();

    delete(blog);
    blog = NULL;
    delete(observer1);
    observer1 = NULL;
    system("pause");
    return 0;
}

四 总结
优点:
1 观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层充当具体观察者角色。
2 观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合,无须了解其具体观察者。由于观察目标和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
3 观察者模式支持广播通信,观察目标会向所有已注册的观察者对象发送通知,简化了一对多系统设计的难度。
4 观察者模式满足“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。

缺点
1 如果一个观察目标对象有很多直接和间接观察者,将所有的观察者都通知到会花费很多时间。
2 如果在观察者和观察目标之间存在循环依赖,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值