Observer:观察者模式

      很多用户的微信号都关注了腾讯官方的微信公众号。当有新的消息时,该公众号就会将信息推送给所有关注者。

      这种情况下,用户微信号就是观察者,腾讯官方微信公众号就是被观察者。用户(观察者)有多个,而腾讯官方(被观察者)只有一个。

      这就是观察者模式:每个观察者将自己注册给被观察者,当被观察者有新的信息时,就通知给所有的观察者。

      cocos2dx的通知功能就使用了观察者模式:当一个类(观察者)需要接受某通知时,就将自己注册给通知管理类(被观察者)。当该通知被发出时,通知管理类就会通知所有对应的观察者,并调用其回调函数。

 

1.    观察者基类及其派生类定义

观察者可能有多种。所以观察者应该定义一个虚基类,该虚基类定义了观察者的标准接口。然后从该虚基类派生出不同的观察者类。

观察者的标准接口允许接收一个被观察者的指针,从而更新自身的状态。

//预定义被观察者
class Subject;

//观察者
class Observer
{
public:
	virtual void Update(Subject* pSubject) = 0;
};

class ConcreteObserverA : public Observer
{
public:
	virtual void Update(Subject* pSubject)
	{
		this->_state = pSubject->GetState();
	}
private:
	string _state;
};

class ConcreteObserverB : public Observer
{
public:
	virtual void Update(Subject* pSubject)
	{
		this->_state = pSubject->GetState();
	}
private:
	string _state;
};

2.    被观察者类定义

被观察者需要保存所有的观察者。

同样地,被观察者可能有多种,所以比较好的做法是像观察者那样定义一个虚基类,然后进行不同类型观察者的派生。这里为了简洁,并没有采用这种方式。

//被观察者
class Subject
{
public:
	virtual void Notify()
	{
		list<Observer*>::iterator iter = this->m_lst.begin();
		for (; iter != m_lst.end(); iter++)
		{
			(*iter)->Update(this);
		}
	};

	//添加观察者
	virtual void Attach(Observer* pObserver)
	{
		this->m_lst.push_back(pObserver);
	};

	//移除观察者
	virtual void Detach(Observer* pObserver)
	{
		list<Observer*>::iterator iter;
		iter = find(m_lst.begin(), m_lst.end(), pObserver);
		if (iter != m_lst.end())
		{
			m_lst.erase(iter);
		}
	};

	virtual string GetState() { return this->_state; }
	virtual void SetState(string state) { this->_state = state; }
private:
	string _state;
	list<Observer*> m_lst;
};

3.    用户使用

用户创建出所有观察者对象及一个被观察者对象。将所有观察者注册给被观察者。这样,当被观察者状态更新时,就会向所有观察者发出通知,并调用观察者的回调接口函数。

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

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

	pSubject->SetState("old");
	//发出通知,令所有观察者状态修改为"old"
	pSubject->Notify();

	pSubject->SetState("new");
	//移除观察者p3
	pSubject->Detach(p3);
	//发出通知,令所有观察者状态修改为"new"
	pSubject->Notify();
}

观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。

观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。

于被观察者而言,它需要改变所有的观察者,但它并不能预知每次有多少观察者被改变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值