1、应用场景
在一个对象的状态改变时更新另外一组对象,例如excel中一个折线图和一个数据表格,使用同一个模型的数据,无论何时更改了模型,都需要更新折线图数据表格。
原理:
(1)Subject类注册Observer
(2)Subject类通知其他对象时,通过修改更新注册时添加对象的状态。
(3)Observer直接获取Subject修改后的状态变量,即实现了该状态变量的输出。
定义步骤:
(1) 定义观察者类:
①、定义和实现状态输出接口
(2)定义观察对象类
①、通过list容器(C++),定义Observer对象的容器
②、Subject类中,实现Observer的注册Attach、撤销Detach,即增加、删除list定义的Observer对象
③、Notify函数中,遍历list定义的Observer对象,将该对象的状态变量更新。
2、UML类图
3、代码实现
3.1 Python
class Observer:
def __init__(self,Observer_Name):
self.Observer_Name=Observer_Name
self.Observer_State=0
def update(self,state):
self.Observer_State = state
print("更新后观察者%d的State值为%d"%(self.Observer_Name,self.Observer_State))
class Subject:
def __init__(self):
self.Subject_State=0
self.Observer_List = []
def Set_State(self,Subject_State):
self.Subject_State=Subject_State
def Attach(self,Observer):
self.Observer_List.append(Observer)
def Detach(self,Observer):
print("删除观察者%d"%Observer.Observer_Name)
self.Observer_List.remove(Observer)
def Notify(self):
for observer in self.Observer_List:
observer.update(self.Subject_State)
if __name__=='__main__':
Subject = Subject()
Observer1 = Observer(1)
Observer2 = Observer(2)
Subject.Attach(Observer1)
Subject.Attach(Observer2)
Subject.Set_State(10)
Subject.Notify()
Subject.Detach(Observer1)
Subject.Notify()
3.2 C++
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Observer
{
public:
virtual void Update(int)=0;
};
class Subject
{
public:
virtual void Attach(Observer*)=0;
virtual void Detach(Observer*)=0;
virtual void Notify() = 0;
};
class ConcreteSubject:public Subject
{
public:
// virtual ConcreteSubject(Observer_Iint){m_Observer=Observer_Iint};
void Attach(Observer *Observer_user)
{
m_Observer.push_back(Observer_user);
}
void Detach(Observer *Observer_user)
{
m_Observer.remove(Observer_user);
}
void Set_State(int state)
{
Subject_State = state;
};
void Notify()
{
list<Observer *>::iterator it = m_Observer.begin();
while(it!=m_Observer.end())
{
(*it)->Update(Subject_State);
++it;
}
};
private:
list<Observer *> m_Observer;
int Subject_State;
};
class ConcreteObserver1:public Observer
{
public:
ConcreteObserver1(Subject *pSubject):m_Subject(pSubject){}
void Update(int state)
{
cout<<"After Update State is :"<< state<<endl;
}
private:
Subject *m_Subject;
};
class ConcreteObserver2:public Observer
{
public:
ConcreteObserver2(Subject *pSubject):m_Subject(pSubject){}
void Update(int state)
{
cout<<"After Update State is :"<< state<<endl;
}
private:
Subject *m_Subject;
};
int main()
{
ConcreteSubject *Subject_1 = new ConcreteSubject();
Observer *Observer_1 =new ConcreteObserver1(Subject_1);
Observer *Observer_2 = new ConcreteObserver2(Subject_1);
Subject_1->Set_State(2);
Subject_1->Attach(Observer_1);
Subject_1->Attach(Observer_2);
Subject_1->Notify();
Subject_1->Detach(Observer_1);
Subject_1->Notify();
return 0;
}