设计模式之观察者模式

需要注意内存释放的先后顺序。

类之间相互调用。

#pragma once
#include <string>
#include <list>

class Observer;

typedef std::string State;

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:
    std::list<Observer *> *m_obvs;
};
#include "Subject.h"
#include "Observer.h"
#include <iostream>


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


Subject::~Subject()
{
    m_obvs->clear();  // 清空list
    if (m_obvs)
    {
        delete m_obvs;
        m_obvs = NULL;
    }
}

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

void Subject::Detach(Observer *obv)
{
    if (obv)
    {
        //std::list<Observer *>::iterator it = find(m_obvs->begin(), m_obvs->end(), obv);
        //m_obvs->erase(it);
        m_obvs->remove(obv);
    }
}

void Subject::Notify()
{
    std::list<Observer *>::iterator it;
    it = m_obvs->begin();
    for (; it != m_obvs->end(); it++)
    {
        (*it)->Update(this);
    }
}

 

#pragma once
#include "Subject.h"
class ConcreateSubject :
    public Subject
{
public:
    ConcreateSubject();
    ~ConcreateSubject();

    State GetState();

    void SetState(const State &st);

private:
    State m_st;
};
#include "ConcreateSubject.h"


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


ConcreateSubject::~ConcreateSubject()
{
}

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

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

 

观察者基类

#pragma once
#include <string>

class  Subject;
typedef std::string State;

class Observer
{
public:
    virtual ~Observer();

    virtual void Update(Subject *sub) = 0;  // 纯虚函数,由子类实现

    virtual void PrintInfo() = 0;  // 纯虚函数,有子类实现

protected:
    Observer();

    State m_st;
};
#include "Observer.h"


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


Observer::~Observer()
{
}

 

观察者A

#pragma once
#include "Observer.h"
class ConcreateObserverA :
    public Observer
{
public:
    ConcreateObserverA(Subject *sub);
    virtual ~ConcreateObserverA();

    virtual Subject *GetSubject();

    void Update(Subject *sub);

    void PrintInfo();

protected:
    Subject *m_sub;
};
#include "ConcreateObserverA.h"
#include "Subject.h"
#include <iostream>


ConcreateObserverA::ConcreateObserverA(Subject *sub)
{
    m_sub = sub;
    m_sub->Attach(this);
}


ConcreateObserverA::~ConcreateObserverA()
{
    m_sub->Detach(this);
}

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

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

void ConcreateObserverA::Update(Subject *sub)
{
    m_st = sub->GetState();

    PrintInfo();
}

 

观察者B

#pragma once
#include "Observer.h"
class ConcreateObserverB :
    public Observer
{
public:
    ConcreateObserverB(Subject *sub);
    virtual ~ConcreateObserverB();

    virtual Subject *GetSubject();

    void Update(Subject *sub);

    void PrintInfo();

private:
    Subject *m_sub;
};
#include "ConcreateObserverB.h"
#include "Subject.h"
#include <iostream>


ConcreateObserverB::ConcreateObserverB(Subject *sub)
{
    m_sub = sub;
    m_sub->Attach(this);
}


ConcreateObserverB::~ConcreateObserverB()
{
    m_sub->Detach(this);
}

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

void ConcreateObserverB::PrintInfo()
{
    std::cout << "ConcreateObserverB::PrintInfo..." << m_sub->GetState() << std::endl;
    return;
}

void ConcreateObserverB::Update(Subject *sub)
{
    m_st = sub->GetState();

    PrintInfo();

    return;
}

 

测试

#include <iostream>
#include "ConcreateSubject.h"
#include "ConcreateObserverA.h"
#include "ConcreateObserverB.h"

int main()
{
    ConcreateSubject *sub = new ConcreateSubject();

    Observer *obs1 = new ConcreateObserverA(sub);

    Observer *obs2 = new ConcreateObserverB(sub);

    sub->SetState("old");

    sub->Notify();  // 轮询更新并显示容器里的观察者

    sub->SetState("new");

    sub->Notify();

    if (obs1)
    {
        delete obs1;
        obs1 = NULL;
    }

    if (obs2)
    {
        delete obs2;
        obs2 = NULL;
    }

   // 在最后释放
if (sub) { delete sub; sub = NULL; } std::cout << "Hello World!\n"; }

 

posted @ 2019-11-01 11:39  N_zero  阅读(166)  评论(0)    收藏  举报