ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码

Observer模式详解--设计模式(15)(2/3)

来源:网络整理     时间:2016-07-02     关键词:

本篇文章主要介绍了" Observer模式详解--设计模式(15)",主要涉及到方面的内容,对于其他编程jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播感兴趣的同学可以参考一下: Observer模式来源: Observer模式应该可以说是应用最多、影响最广的模式之一。 因为Observer的一个实例Mod...

             Observer模式详解--设计模式(15)

Observer模式的构成:

      Subject类:可翻译为主题或抽象通知者,一般用一个抽象类或者一个借口实现。它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个借口,可以增加和删除观察者对象。

      Observer类:抽象观察者,为所有的具体观察者定义一个借口,在得到主题的通知时更新自己。这个借口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。更新接口通常包含一个Update()方法。

      ConcreteSubject类:叫做具体主题或具体通知者,将有关状态存入具体通知者对象;在具体主题的内部状态改变时,给所有等级过的观察者发出通知。通常用一个具体子类实现。

      ConcreteObserver类:具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。具体观察者角色可以保存一个指向一个具体主题对象的引用。

Observer模式的代码示例:

Observer.h

#ifndef _OBSERVER_H_
#define _OBSERVER_H_

#include 
#include 
using namespace std;

class Subject;

class Observer
{
public:
    ~Observer();
    virtual void Update(Subject*)=0;
protected:
    Observer();
private:
};

class ConcreteObserverA : public Observer
{
public:
    ConcreteObserverA();
    ~ConcreteObserverA();
    virtual void Update(Subject*);
protected:
private:
    string m_state;
};

class ConcreteObserverB : public Observer
{
public:
    ConcreteObserverB();
    ~ConcreteObserverB();
    virtual void Update(Subject*);
protected:
private:
    string m_state;
};

class Subject
{
public:
    ~Subject();
    virtual void Notify();
    virtual void Attach(Observer*);
    virtual void Detach(Observer*);
    virtual string GetState();
    virtual void SetState(string state);
protected:
    Subject();
private:
    string m_state;
    list m_lst;
};

class ConcreteSubjectA : public Subject
{
public:
    ConcreteSubjectA();
    ~ConcreteSubjectA();
protected:
private:
};

class ConcreteSubjectB : public Subject
{
public:
    ConcreteSubjectB();
    ~ConcreteSubjectB();
protected:
private:
};

#endif

Observer.cpp

#include "Observer.h"
#include 
#include 

using namespace std;

Observer::Observer()
{}

Observer::~Observer()
{}

ConcreteObserverA::ConcreteObserverA()
{}

ConcreteObserverA::~ConcreteObserverA()
{}

void ConcreteObserverA::Update(Subject* pSubject)
{
    this->m_state = pSubject->GetState();
    cout << "The ConcreteObserverA is " << m_state << std::endl;
}

ConcreteObserverB::ConcreteObserverB()
{}

ConcreteObserverB::~ConcreteObserverB()
{}

void ConcreteObserverB::Update(Subject* pSubject)
{
    this->m_state = pSubject->GetState();
    cout << "The ConcreteObserverB is " << m_state << std::endl;
}

Subject::Subject()
{}

Subject::~Subject()
{}

void Subject::Attach(Observer* pObserver)
{
    this->m_lst.push_back(pObserver);
    cout << "Attach an Observer\n";
}

void Subject::Detach(Observer* pObserver)
{
    list::iterator iter;
    iter = find(m_lst.begin(),m_lst.end(),pObserver);
    if(iter != m_lst.end())
    {
        m_lst.erase(iter);
    }
    cout << "Detach an Observer\n";
}

void Subject::Notify()
{
    list::iterator iter = this->m_lst.begin();
    for(;iter != m_lst.end();iter++)
    {
        (*iter)->Update(this);
    }
}

string Subject::GetState()
{
    return this->m_state;
}

void Subject::SetState(string state)
{
    this->m_state = state;
}

ConcreteSubjectA::ConcreteSubjectA()
{}

ConcreteSubjectA::~ConcreteSubjectA()
{}

ConcreteSubjectB::ConcreteSubjectB()
{}

ConcreteSubjectB::~ConcreteSubjectB()
{}
Main.cpp
#include "Observer.h"
#include 

using namespace std;

int main()
{
    Observer* p1 = new ConcreteObserverA();
    Observer* p2 = new ConcreteObserverB();
    Observer* p3 = new ConcreteObserverA();

    Subject* pSubject = new ConcreteSubjectA();
    pSubject->Attach(p1);
    pSubject->Attach(p2);
    pSubject->Attach(p3);

    pSubject->SetState("old");

    pSubject->Notify();

    cout << "-------------------------------------" << endl;
    pSubject->SetState("new");

    pSubject->Detach(p3);
    pSubject->Notify();

    return 0;
}

        在Observer模式的实现中,Subject维护一个list作为存储其所有观察者的容器。每当调用Notify操作就遍历list中的Observer对象,并广播通知改变状态(调用Observer的Update操作)。目标的状态state可以由Subject自己改变(示例),也可以由Observer的某个操作引起state的改变(可调用Subject的SetState操作)。Notify操作可以由Subject目标主动广播(示例),也可以由Observer观察者来调用(因为Observer维护一个指向Subject的指针)。运行示例程序,可以看到当Subject处于状态“old”时候,依赖于它的两个观察者都显示“old”,当目标状态改变为“new”的时候,依赖于它的两个观察者也都改变为“new”。

Observer模式使用场景:

(1).当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
(2).观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。

Observer模式优缺点总结:

观察者模式的优点:

(1). Subject和Observer之间是松耦合的,分别可以各自独立改变。

(2). Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。

(3). 遵守大部分GRASP原则和常用设计原则,高内聚、低耦合。

观察者模式的缺点:

(1).松耦合导致代码关系不明显,有时可能难以理解。(废话)

(2). 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历)

相关图片

相关文章