定义对象间的一种一对多的依赖关系,使得当一个对象subject的状态发生变化时,所有依赖于它的对象都得到通知并自动更新
在subject中定义被观察者,在object中定义观察者(变化的部分)
将接口方法抽象到父类中,Isubject Iobject(稳定的部分)
无论添加多少个观察者,被观察者保持不变(达到了松耦合),发送通知时 无需理会观察者直接进行发送。
(就是怎样更加松耦合的实现,一个类的对象发出的同时被另一个类的一堆对象获取。)
#include <iostream>
#include <list>
#include <string>
#include <memory>
using namespace std;
class IObject{//创建观察者父类(理解成用户) 包含了update方法 稳定
public:
virtual void update(const string& s) = 0;
};
class ISubject{ //创建被观察者(可以理解成公众号 )一般包含add del notify(一般都是用户进行add操作)稳定
public:
virtual ~ISubject(){}
virtual void AddNew(IObject *obj) = 0;
virtual void Del(IObject *obj) = 0;
virtual void Notify() = 0;
};
class Subject:public ISubject{//具体被观察者,一般是不稳定
public:
virtual ~Subject(){}
private:
/* 下面这行是重点*/
list<IObject*>_Obj;//多态指针 为了能给所有用户发通知
string _message = "None";
public://重写父类方法
void AddNew(IObject *obj) override{
_Obj.push_back(obj);
}
void Del(IObject *obj) override{
_Obj.remove(obj);
}
virtual void Notify(){
//使用多态指针 给每个用户进行通知(发消息)
for(auto i : _Obj){
i->update(_message);
}
}
void CreateMessage(string message="empty"){
this->_message = message;
}
int Size_Obj(){
return _Obj.size();
}
};
class Object:public IObject{
public:
Object(){} //用户创建用户
Object(Subject* sub){ //在创建用户时就直接绑定公众号(sub)
this->_sub = sub;
this->_sub->AddNew(this);
cout<<"hello object"<<++this->_num<<endl;
}
void RemoveFromList(){
this->_sub->Del(this); // 观察者将自己与被观察者解除关联
this->_num--;
cout<<"Del self"<<endl;
}
//重写方法 用来执行用户在收到消息后的操作
void update(const string& s) override{
cout<<"object"<<"\treviced"<<"\t"<<s<<endl;
}
private:
ISubject* _sub; //多态指针
static int _num;
int _num2 = 0;
};
int Object::_num = 0;
int main(int argc, char const *argv[])
{
//shared_ptr<Subject>sub(new Subject); //如果使用智能指针的话 需要在类内也进行改写
// shared_ptr<Object>obj(new Object(sub));
//Object *obj = new Object(sub);
//sub->AddNew(obj);
// shared_ptr<Object>obj1(new Object(sub));
Subject *sub = new Subject();
Object *obj1 = new Object(sub);
Object *obj2 = new Object();
sub->AddNew(obj2);
sub->Notify();
obj1->RemoveFromList();
sub->CreateMessage("We are family");
cout<<sub->Size_Obj()<<endl;
sub->Notify();
delete sub;
delete obj1;
delete obj2;
return 0;
}
重点总结:
使用面向对象的抽象,Observer模式使得我们可以独立的改变观察者与被观察者,从而使二者之间的依赖关系达到松耦合
被观察者发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播
观察者决定是否需要订阅通知,被观察者对此一无所知
Observer模式是基于时间的UI框架中非常常用的设计模式,也是mvc模式的一个重要组成部分