观察者模式学习

来源:互联网 发布:思科网络切换 编辑:程序博客网 时间:2024/04/28 13:13

1. 将数据和“数据的视图”进行分离,保持两者之间的低耦合。

2. “数据类”保持独立性,“视图类”依赖“数据类”

3. “数据类”中维护所有视图实例的引用(顶级父类引用),“视图类”中维护所依赖的数据实例的引用。

4. 数据发生更新时数据实例根据“视图类”所提供的接口,执行更新操作。

#include <iostream>#include <vector>using namespace std;class Subject {    vector <class Observer* > views;  /* observer 父类指针 */    int value;/* 数据 */  public:    void attach(Observer *obs) {        views.push_back(obs);    }    void setVal(int val)/* 更新数据,同时通知观察者读取数据 */{        value = val;        notify();    }    int getVal() {        return value;    }    void notify();};class Observer {       Subject *model;    /* 指针指向观察者所依赖的“数据”实例 */    int denom;  public:    Observer(Subject *mod, int div){        model = mod;        denom = div;        model->attach(this);/* 将自己加入到“数据”所维护的观察者集合中 */    }    virtual void update() = 0;  /* 数据读取方式由具体子类进行实现 */  protected:                   /* 以下方法客户没法进行访问 */    Subject* getSubject() {        return model;    }    int getDivisor() {        return denom;    }};void Subject::notify() {for (int i = 0; i < views.size(); i++)views[i]->update();     /* 不同的观察者有不同的数据读取方式,此处为多态,update()是父类方法 */}/* 不同观察者的具体实现  */class DivObserver: public Observer {  public:    DivObserver(Subject *mod, int div): Observer(mod, div){}    void update() {         int v = getSubject()->getVal(), d = getDivisor();        cout << v << " div " << d << " is " << v / d << '\n';    }};class ModObserver: public Observer {  public:    ModObserver(Subject *mod, int div): Observer(mod, div){}    void update(){        int v = getSubject()->getVal(), d = getDivisor();        cout << v << " mod " << d << " is " << v % d << '\n';    }};int main() {  Subject subj;  DivObserver divObs1(&subj, 4);   DivObserver divObs2(&subj, 3);   ModObserver modObs3(&subj, 3);  subj.setVal(14);}


0 0
原创粉丝点击