观察者模式学习

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);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值