观察者模式

1. 概念解析

1.1 理解

  Observer模式要解决的问题为:建立一个一(Subject)对多(Observer)的依赖关系,并且做到当“一”变化的时候,依赖这个“一”的多也能够同步改变。最常见的一个例子就是:对同一组数据进行统计分析时候,我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有的统计的显示都能够同时改变。Observer模式就是解决了这一个问题。

1.2 类图

在这里插入图片描述
在这里插入图片描述

2. 示例代码

2.1 示例1

Subject.h

//Subject.h
#ifndef _SUBJECT_H_
#define _SUBJECT_H_

#include<list>
#include<string>

using namespace std;

typedef string State;
class Observer;

class Subject
{
public:
    virtual ~Subject();
    virtual void Attach(Observer *obv);
    virtual void Detach(Observer *obv);
    virtual void Notify();
    virtual void SetState(const State& st) = 0;
    virtual State GetState() = 0;
protected:
    Subject();
private:
    list<Observer *> *m_obvs;
};

class ConcreteSubject : public Subject
{
public:
    ConcreteSubject();
    ~ConcreteSubject();
    State GetState();
    void SetState(const State& st);
private:
    State m_st;
};

#endif

Subject.cpp

#include"Subject.h"
#include"Observer.h"

Subject::Subject()
{
    m_obvs = new list<Observer *>;
}

Subject::~Subject()
{

}

void Subject::Attach(Observer *obv)
{
    m_obvs->push_back(obv);
}

void Subject::Detach(Observer *obv)
{
    if (NULL != m_obvs)
    {
        m_obvs->remove(obv);
    }
}

void Subject::Notify()
{
    list<Observer *>::iterator it;
    it = m_obvs->begin();

    for (; it != m_obvs->end(); it++)
    {
        (*it)->Update(this);
    }
}

ConcreteSubject::ConcreteSubject()
{
    m_st = '\0';
}

ConcreteSubject::~ConcreteSubject()
{ 

}

State ConcreteSubject::GetState()
{
    return m_st;
}

void ConcreteSubject::SetState(const State& st)
{
    m_st = st;
}

Observer.h

#ifndef _OBSERVER_H_
#define _OBSERVER_H_

#include "Subject.h"
#include<iostream>
#include <string>

using namespace std;
typedef string State;

class Observer
{
public:
    virtual ~Observer();
    virtual void Update(Subject *sub) = 0;
    virtual void PrintInfo() = 0;
protected:
    Observer();
    State m_st;
};

class ConcreteObserverA : public Observer
{
public:
    virtual Subject* GetSubject();
    ConcreteObserverA(Subject* sub);
    virtual ~ConcreteObserverA();
    //传入Subject作为参数,这样可以让一个View属于多个的Subject。
    void Update(Subject* sub);
    void PrintInfo();
private:
    Subject* m_sub;
};

class ConcreteObserverB :public Observer
{
public:
    virtual Subject* GetSubject();
    ConcreteObserverB(Subject* sub);
    virtual ~ConcreteObserverB();
    //传入Subject作为参数,这样可以让一个View属于多个的Subject。
    void Update(Subject* sub);
    void PrintInfo();
private:
    Subject* m_sub;
};

#endif


Observer.cpp

#include "Observer.h"

Observer::Observer()
{
    m_st = '\0';
}
Observer::~Observer()
{
}
ConcreteObserverA::ConcreteObserverA(Subject* sub)
{
    m_sub = sub;
    m_sub->Attach(this);
}

ConcreteObserverA::~ConcreteObserverA()
{
    m_sub->Detach(this);
    if (m_sub != 0)
        delete m_sub;
}
Subject* ConcreteObserverA::GetSubject()
{
    return m_sub;
}

void ConcreteObserverA::PrintInfo()
{
    cout << "ConcreteObserverA observer.... " << m_sub->GetState() << endl;
}
void ConcreteObserverA::Update(Subject* sub)
{
    m_st = sub->GetState();
    PrintInfo();
}
ConcreteObserverB::ConcreteObserverB(Subject* sub)
{
    m_sub = sub;
    m_sub->Attach(this);
}

ConcreteObserverB::~ConcreteObserverB()
{
    m_sub->Detach(this);
    if (m_sub != 0)
    {
        delete m_sub;
    }
}

Subject* ConcreteObserverB::GetSubject()
{
    return m_sub;
}

void ConcreteObserverB::PrintInfo()
{
    cout << "ConcreteObserverB observer.... " << m_sub->GetState() << endl;
}

void ConcreteObserverB::Update(Subject* sub)
{
    m_st = sub->GetState();
    PrintInfo();
}

main.cpp

#include "Subject.h"
#include "Observer.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
    ConcreteSubject* sub = new ConcreteSubject();
    Observer* o1 = new ConcreteObserverA(sub);
    Observer* o2 = new ConcreteObserverB(sub);

    sub->SetState("old");
    sub->Notify();

    sub->SetState("new"); //也可以由Observer调用
    sub->Notify();

    system("pause");
    return 0;
}

在这里插入图片描述

2.2 示例2

observerTest.cpp

#include<iostream>
#include<list>

using namespace std;

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

class CSubject
{
public:
    virtual void attach(CObserver *) = 0;  //绑定函数
    virtual void detach(CObserver *) = 0;  //解绑定函数
    virtual void notify() = 0;  //通知函数
};

class CConcreteObserver : public CObserver
{
public:
    CConcreteObserver(CSubject *pSubject) :m_pSubject(pSubject)
    {

    }

    void update(int value)
    {
        cout <<"ConcreteObserver get the update. New State:"<< value<<endl;
    }

private:
    CSubject *m_pSubject;
};

class CConcreteObserver2 : public CObserver
{
public:
    CConcreteObserver2(CSubject *pSubject) : m_pSubject(pSubject){}

    void update(int value)
    {
        cout<<"ConcreteObserver2 get the update. New State:" << value << endl;
    }

private:
    CSubject *m_pSubject;
};

class CConcreteSubject : public CSubject
{
public:
    void attach(CObserver *pObserver);
    void detach(CObserver *pObserver);
    void notify();

    void SetState(int state)
    {
        m_iState = state;
    }

private:
    std::list<CObserver *> m_ObserverList;
    int m_iState;
};

void CConcreteSubject::attach(CObserver *pObserver)
{
    m_ObserverList.push_back(pObserver);
}

void CConcreteSubject::detach(CObserver *pObserver)
{
    m_ObserverList.remove(pObserver);
}

void CConcreteSubject::notify()
{
    std::list<CObserver *>::iterator it = m_ObserverList.begin();
    while (it != m_ObserverList.end())
    {
        (*it)->update(m_iState);
        ++it;
    }
}

int main()
{
    // Create Subject
    CConcreteSubject *pSubject = new CConcreteSubject();

    // Create Observer
    CObserver *pObserver = new CConcreteObserver(pSubject);
    CObserver *pObserver2 = new CConcreteObserver2(pSubject);

    // Change the state
    pSubject->SetState(2);

    // Register the observer
    pSubject->attach(pObserver);
    pSubject->attach(pObserver2);

    pSubject->notify();

    // Unregister the observer
    pSubject->detach(pObserver);

    pSubject->SetState(3);
    pSubject->notify();

    delete pObserver;
    delete pObserver2;
    delete pSubject;

    system("pause");
    return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值