zoukankan      html  css  js  c++  java
  • 观察者模式

    观察者模式(Observer Pattern) —— 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

    观察者模式可以理解为发布-订阅模式,即多个订阅者(观察者)向发布者(被观察者)订阅状态信息,当发布者更新状态时会将状态信息向它的订阅者发布信息。发布者需要自己维护订阅者列表,可以注册或者注销对状态信息感兴趣或不感兴趣的订阅者。

    // subject.h
    #include<vector>
    #include<string>
    using namespace std;
    

    typedef int State;

    class Observer;

    // 被观察者(发布者)抽象
    class Subject {
    public:
    Subject(){}
    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;

    private:
    //观察者列表
    vector<Observer*> m_pObs;
    };

    // 被观察者(实际发布者)
    class ConcreteSubject: public Subject
    {
    public:
    ConcreteSubject(){}
    ~ConcreteSubject(){}
    State GetState();
    void SetState(const State& st);

    private:
    State m_state;
    };

    // subject.cpp
    #include "subject.h"
    #include "observer.h"
    
    void Subject::Attach(Observer* pObs)
    {
        m_pObs.push_back(pObs);
    }
    
    void Subject::Detach(Observer* pObs)
    {
        vector<Observer*>::iterator it = m_pObs.begin();
        for ( ;it!=m_pObs.end();++it)
        {
            if (*it == pObs)
            {
                m_pObs.erase(it);
                return;
            }
        }
    }
    
    void Subject::Notify()
    {
        vector<Observer*>::iterator it = m_pObs.begin();
        for ( ; it!=m_pObs.end(); ++it)
        {
             (*it)->update(this);
        }
    }
    
    void ConcreteSubject::SetState(const State& st)
    {
         m_state = st;
    }
    
    State ConcreteSubject::GetState()
    {
         return m_state;
    }
    // observer.h
    #include<iostream>
    #include<string>
    #include<vector>
    using namespace std;
    
    typedef int State;
    
    class Subject;
    
    // 观察者抽象
    class Observer {
    public:
        Observer(){}
        virtual ~Observer(){}
        virtual void update(Subject* sub) = 0;
        virtual void outputState();
    
    protected:
        string m_name;
        State m_observerState;
    };
    
    // 实际观察者A
    class ConcreteObserverA: public Observer {
    public:
        ConcreteObserverA(string name, State init_state){
            m_name = name;
            m_observerState = init_state;
        }
        ~ConcreteObserverA(){}
        void update(Subject* sub);
    
    private:
    //    Subject* m_sub;
    };
    
    // 实际观察者B
    class ConcreteObserverB: public Observer {
    public:
        ConcreteObserverB(string name, State init_state){
            m_name = name;
            m_observerState = init_state;
        }
        ~ConcreteObserverB(){}
        void update(Subject* sub);
    
    private:
    //    Subject* m_sub;
    };
    // observer.cpp
    #include "observer.h"
    #include "subject.h"
    
    void Observer::outputState()
    {
        cout<<m_name<<" update state :"<<m_observerState<<endl;
    }
    
    void ConcreteObserverA::update(Subject* sub)
    {
        m_observerState = sub->GetState();
        outputState();
    }
    
    void ConcreteObserverB::update(Subject* sub)
    {
        m_observerState = sub->GetState();
        outputState();
    }
    // main.cpp
    #include "observer.h"
    #include "subject.h"
    
    int main()
    {
        ConcreteSubject* subject = new ConcreteSubject();
        Observer* obA = new ConcreteObserverA("observerA", -1);
        Observer* obB = new ConcreteObserverB("observerB", -1);
        subject->Attach(obA);
        subject->Attach(obB);
    
        subject->SetState(0);
        subject->Notify();
    
        subject->Detach(obA);
        subject->SetState(1);
        subject->Notify();
    
        delete obA;
        delete obB;
        delete subject;
    
        return 0;
    }
    
    // 输出结果:
    //observerA update state :0
    //observerB update state :0
    //observerB update state :1
  • 相关阅读:
    js压缩、混淆和加密 Alan
    与、或、异或运算 Alan
    Hello world Alan
    abstract class和interface有什么区别?
    接口是否可继承接口? 抽像类是否可实现(implements)接口? 抽像类是否可继承实体类(concrete class)?
    启动一个线程是用run()还是start()?
    数组有没有length()这个方法? String有没有length()这个方法?
    swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
    当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
    简要谈一下您对微软.NET 构架下remoting和webservice两项技术的理解以及实际中的应用。
  • 原文地址:https://www.cnblogs.com/ylaoda/p/11976770.html
Copyright © 2011-2022 走看看