Observer 模式 观察者模式
来源:互联网 发布:爱奇艺数据怎么删除 编辑:程序博客网 时间:2024/04/27 21:29
//Subject.h
#include<list>
#include<string>
usingnamespace std;
typedef string State;
class Observer;
class Subject
{
public:
virtual~Subject();
virtualvoid Attach(Observer* obv);
virtualvoid Detach(Observer* obv);
virtualvoid Notify();
virtualvoid SetState(const State& 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);
private:
State _st;
};
//Subject.cpp
#include"Subject.h"
#include"Observer.h"
#include<iostream>
#include<list>
usingnamespace std;
typedef string state;
Subject::Subject()
{
//在模板的使用之前一定要 new,创建
_obvs = new list<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()
{
}
State ConcreteSubject::GetState()
{
return _st;
}
void ConcreteSubject::SetState(const State& st)
{
_st = st;
}
//Observer.h
#include"Subject.h"
#include<string>
usingnamespace std;
typedef string State;
class Observer
{
public:
virtual~Observer();
virtualvoid Update(Subject* sub)=0;
virtualvoid PrintInfo()= 0;
protected:
Observer();
State _st;
};
class ConcreteObserverA:public Observer
{
public:
virtual Subject* GetSubject();
ConcreteObserverA(Subject* sub);
virtual~ConcreteObserverA();
//传入 Subject作为参数,这样可以让一个View 属于多个的 Subject 。
void Update(Subject* sub);
void PrintInfo();
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();
private:
Subject* _sub;
};
//Observer.cpp
#include"Observer.h"
#include"Subject.h"
#include<iostream>
#include<string>
usingnamespace std;
Observer::Observer()
{
_st = '\0';
}
Observer::~Observer()
{
}
ConcreteObserverA::ConcreteObserverA(Subject* 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<<"ConcreteObserverA observer..."<<_sub->GetState()<<endl;
}
Void ConcreteObserverA::Update(Subject* sub)
{
_st = sub->GetState();
PrintInfo();
}
ConcreteObserverB::ConcreteObserverB(Subject* sub)
{
_sub = sub;
_sub->Attach(this);
}
#include"Subject.h"
#include"Observer.h"
#include<iostream>
usingnamespace std;
int main(int argc,char* argv[])
{
ConcreteSubject* sub=newConcreteSubject();
Observer* o1=new ConcreteObserverA(sub);
Observer* o2=new ConcreteObserverB(sub);
sub->SetState("old");
sub->Notify();
sub->SetState("new");//也可以由Observer调用
sub->Notify();
return0;
}
在 Observer模式的实现中,Subject维护一个 list作为存储其所有观察者的容器。每当
调用Notify操作就遍历list中的Observer对象,并广播通知改变状态(调用Observer的Update操作)。目标的状态 state可以由 Subject自己改变(示例),也可以由 Observer的某个操作引起 state的改变(可调用Subject的 SetState操作)。Notify操作可以由 Subject目标主动广播(示例),也可以由 Observer观察者来调用(因为 Observer维护一个指向Subject的指针)。
运行示例程序,可以看到当 Subject处于状态“old”时候,依赖于它的两个观察者都显
示“old”,当目标状态改变为“new”的时候,依赖于它的两个观察者也都改变为“new”。
大型系统开发过程中要用到的模式之一。
除了 MFC、 Struts提供了 MVC 的实现框架,在 Java语言中还提供了专门的接口实现 Observer模式:通过专门的类 Observable及 Observer接口来实现 MVC编程模式,其 UML图可以表示为:
Java中实现 MVC的 UML图。
这里的 Observer就是观察者,Observable则充当目标 Subject的角色。
Observer模式也称为发布-订阅(publish-subscribe),目标就是通知的发布者,观察者则是通知的订阅者(接受通知)。
- Observer 模式 观察者模式
- Observer模式 观察者模式
- 观察者模式(OBSERVER)
- 观察者(Observer)模式
- 观察者模式(Observer Pattern)
- 观察者(Observer)模式
- Observer(观察者)模式
- 观察者(Observer)模式
- 观察者(Observer)模式
- 观察者模式-Observer
- 观察者(Observer)模式
- 观察者设计模式Observer
- 观察者模式(Observer Pattern)
- 观察者(Observer)模式
- 观察者模式(Observer Pattern)
- Observer 观察者模式
- 观察者模式(Observer Pattern)
- Observer观察者模式小结
- DOS 文件名时间戳的生成
- execl() 函数的简单使用
- X86通用寄存器的名称
- JQUERY实时监听input值变化
- 工厂模式
- Observer 模式 观察者模式
- CreateProcess
- Ubuntu 12.04下安装QQ 2012 Beta3(转)
- 最大连续乘积
- 接口
- make menuconfig 出错
- 【Git入门之十三】Ubuntu和git
- 用vmware安装redhat 9出现“光盘无法被挂载”错误的解决办法
- 少年,你的一个Hello World 有多小?