设计模式(19)-行为型模式-OBSERVER模式

本文深入探讨了观察者模式的概念、结构、协作和C++代码实现,包括Subject、Observer、ConcreteSubject和ConcreteObserver类的定义与用法。通过具体的实现案例,展示了如何在软件设计中灵活运用观察者模式进行解耦与通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.7.1 功能

别名:依赖(Dependents),  发布-订阅( P u b l i s h - S u b s c r i b e)

这种交互也称为发布-订阅 (pu b l i s h - s u b s c r i b e) 。发布者发出通知时并不需知道谁是它的观察者。可以有任意数目的观察者订阅并接收通知。

3.7.2 结构

 

•S u b j e c t(目标)

— 目标知道它的观察者。可以有任意多个观察者观察同一个目标。

— 提供注册和删除观察者对象的接口。

•  O b s e r v e r(观察者)

— 为那些在目标发生改变时需获得通知的对象定义一个更新接口。

•  C o n c r e t e S u b j e c t(具体目标)

— 将有关状态存入各C o n c r e t e O b s e r v e r对象。

— 当它的状态发生改变时,  向它的各个观察者发出通知。

•  C o n c r e t e O b s e r v e r(具体观察者)

— 维护一个指向Co n c r e t e S u b j e c t对象的引用。

— 存储有关状态,这些状态应与目标的状态保持一致。

— 实现Ob s e r v e r的更新接口以使自身状态与目标的状态保持一致。

 

基于C h a n g e M a n a g e r的Ob s e r v e r模式的实现:

 

3.7.3 协作

 

注意发出改变请求的O b s e r v e r对象并不立即更新, 而是将其推迟到它从目标得到一个通知之后。No t i f y不总是由目标对象调用。它也可被一个观察者或其它对象调用。实现一节将讨论一些常用的变化。

3.7.4 C++代码示例

//Subject.h

#ifndef _SUBJECT_H_

#define _SUBJECT_H_

#include<list>

#include<string>

using namespace std;

typedefstring State;

 

class Observer;

 

classSubject

{

public:

       virtual ~Subject();

       virtual void Attach(Observer* obv);

       virtual voidDetach(Observer* obv);

       virtual voidNotify();

       virtual voidSetState(constState&st) = 0;

       virtual State GetState() = 0;

protected:

       Subject();

private:

       list<Observer*>* _obvs;

};

class ConcreteSubject :public Subject

{

public:

       ConcreteSubject();

       ~ConcreteSubject();

       State GetState();

       void SetState(const State&st);

protected:

private:

       State _st;

};

#endif //~_SUBJECT_H_

 

//Subject.cpp

#include"Subject.h"

#include"Observer.h"

#include<iostream>

#include<list>

using namespace std;

typedefstringstate;

Subject::Subject()

{ //在模板的使用之前一定要new,创建

       _obvs = newlist<Observer*>;

}

Subject::~Subject()

{}

void Subject::Attach(Observer* obv)

{

       _obvs->push_front(obv);

}

void Subject::Detach(Observer* obv)

{

       if (obv != NULL)

              _obvs->remove(obv);

}

void Subject::Notify()

{

       list<Observer*>::iterator it;

       it = _obvs->begin();

       for (; it != _obvs->end(); it++)

       { //关于模板和iterator的用法

              (*it)->Update(this);

       }

}

ConcreteSubject::ConcreteSubject()

{

       _st = '\0';

}

ConcreteSubject::~ConcreteSubject()

{}

StateConcreteSubject::GetState()

{

       return _st;

}

void ConcreteSubject::SetState(const State&st)

{

       _st = st;

}

 

//Observer.h

#ifndef _OBSERVER_H_

#define _OBSERVER_H_

#include "Subject.h"

#include <string>

using namespace std;

typedef string State;

class Observer

{

public:

       virtual ~Observer();

       virtual voidUpdate(Subject*sub) = 0;

       virtual voidPrintInfo() = 0;

protected:

       Observer();

       State _st;

private:

};

 

class ConcreteObserverA :public Observer

{

public:

       virtual Subject*GetSubject();

       ConcreteObserverA(Subject* sub);

       virtual ~ConcreteObserverA();

       //传入Subject作为参数,这样可以让一个

       View属于多个的Subject。

              void Update(Subject* sub);

       void PrintInfo();

protected:

private:

       Subject* _sub;

};

class ConcreteObserverB :public Observer

{

public:

       virtual Subject*GetSubject();

       ConcreteObserverB(Subject* sub);

       virtual ~ConcreteObserverB();

       //传入Subject作为参数,这样可以让一个View属于多个的Subject

       void Update(Subject* sub);

       void PrintInfo();

protected:

private:

       Subject* _sub;

};

#endif //~_OBSERVER_H_

 

//Observer.cpp

#include "Observer.h"

#include "Subject.h"

#include <iostream>

#include <string>

using namespace std;

Observer::Observer()

{

       _st = '\0';

}

Observer::~Observer()

{

}

ConcreteObserverA::ConcreteObserverA(Subje

       ct* sub)

{

       _sub = sub;

       _sub->Attach(this);

}

ConcreteObserverA::~ConcreteObserverA()

{

       _sub->Detach(this);

       if (_sub != 0)

              delete _sub;

}

Subject*ConcreteObserverA::GetSubject()

{

       return _sub;

}

void ConcreteObserverA::PrintInfo()

{

       cout << "ConcreteObserverAobserver....

              "<<_sub->GetState()<<endl;

}

void ConcreteObserverA::Update(Subject* sub)

{

       _st = sub->GetState();

       PrintInfo();

}

ConcreteObserverB::ConcreteObserverB(Subje

       ct* sub)

{

       _sub = sub;

       _sub->Attach(this);

}

 

ConcreteObserverB::~ConcreteObserverB()

{

       _sub->Detach(this);

       if (_sub != 0)

       {

              delete _sub;

       }

}

Subject*ConcreteObserverB::GetSubject()

       {

              return _sub;

       }

 

void ConcreteObserverB::PrintInfo()

{

       cout << "ConcreteObserverBobserver....

              "<<_sub->GetState()<<endl;

}

 

void ConcreteObserverB::Update(Subject* sub)

{

       _st = sub->GetState();

       PrintInfo();

}

 

//main.cpp

#include"Subject.h"

#include"Observer.h"

#include<iostream>

using namespace std;

int main(int argc, char*argv[])

{

       ConcreteSubject* sub = new

              ConcreteSubject();

       Observer* o1 = new

              ConcreteObserverA(sub);

       Observer* o2 = new

              ConcreteObserverB(sub);

       sub->SetState("old");

       sub->Notify();

       sub->SetState("new");  // 也可以由Observer调用

              sub->Notify();

       return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值