观察者模式
观察者模式属于行为模式,其特点是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式中存在目标和观察者两个角色,目标作为被观察的对象,当目标更新后,观察者可以自动更新目标的相应状态。但有一点值得注意,目标和观察者不能形成环路,即如果被观察对象之前存在相互依赖,观察者模式会崩溃。
代码
此处以CSDN博客以及CSDN博客订阅者来说明观察者模式的应用。此处CSDN博客作为目标,CSDN博客订阅者作为观察者,当CSDN博客更新时,会给其所有订阅者发送更新消息,从而让CSDN博客订阅者了解CSDN博客的更新。
C++代码
文件结构:
—include
——Blog.h
——BlogCSDN.h
——Observer.h
——ObserverBlog.h
—src
——Blog.cpp
——BlogCSDN.cpp
——Observer.cpp
——ObserverBlog.cpp
——main.cpp
代码如下:
—include/Blog.h
#ifndef _BLOG_H_
#define _BLOG_H_
#include<memory>
#include<string>
#include"Observer.h"
#include<list>
class Blog
{
public:
virtual ~Blog();
void Attach(std::shared_ptr<Observer> tempObserver);
void Detach(std::shared_ptr<Observer> tempObserver);
void Notify();
virtual void SetStatus(const std::string& str);
std::string GetStatus();
protected:
std::string status;
private:
std::list<std::shared_ptr<Observer> > observerList;
};
#endif
—include/BlogCSDN.h
#ifndef _BLOGCSDN_H_
#define _BLOGCSDN_H_
#include"Blog.h"
#include<string>
class BlogCSDN:public Blog
{
public:
BlogCSDN(const std::string& name);
~BlogCSDN();
void SetStatus(const std::string& str);
private:
std::string blogName;
};
#endif
—include/Observer.h
#ifndef _OBSERVER_H_
#define _OBSERVER_H_
class Observer
{
public:
virtual ~Observer();
virtual void Update()=0;
};
#endif
—include/ObserverBlog.h
#ifndef _OBSERVERBLOG_H_
#define _OBSERVERBLOG_H_
#include"Observer.h"
#include<memory>
#include"Blog.h"
#include<string>
class ObserverBlog:public Observer
{
public:
ObserverBlog(const std::string name, std::shared_ptr<Blog> tempBlog);
~ObserverBlog();
void Update();
private:
std::shared_ptr<Blog> observerBlog;
std::string observerName;
};
#endif
—src/Blog.cpp
#include"Blog.h"
#include"ObserverBlog.h"
using namespace std;
Blog::~Blog()
{
;
}
void Blog::Attach(shared_ptr<Observer> tempObserver)
{
observerList.push_back(tempObserver);
}
void Blog::Detach(shared_ptr<Observer> tempObserver)
{
observerList.remove(tempObserver);
}
void Blog::Notify()
{
for(auto it=observerList.begin();it!=observerList.end();++it)
{
(*it)->Update();
}
}
void Blog::SetStatus(const std::string& str)
{
status=str;
}
string Blog::GetStatus()
{
return status;
}
—src/BlogCSDN.cpp
#include"BlogCSDN.h"
using namespace std;
BlogCSDN::BlogCSDN(const string& name):blogName(name)
{
;
}
BlogCSDN::~BlogCSDN()
{
;
}
void BlogCSDN::SetStatus(const string& str)
{
status=blogName+" "+str;
}
—src/Observer.cpp
#include"Observer.h"
Observer::~Observer()
{
;
}
—src/ObserverBlog.cpp
#include"ObserverBlog.h"
#include<iostream>
using namespace std;
ObserverBlog::ObserverBlog(const string name, shared_ptr<Blog> tempBlog):observerName(name),observerBlog(tempBlog)
{
;
}
ObserverBlog::~ObserverBlog()
{
;
}
void ObserverBlog::Update()
{
cout<<observerName<<" "<<observerBlog->GetStatus()<<endl;
}
—src/main.cpp
#include<iostream>
#include<memory>
#include"BlogCSDN.h"
#include"ObserverBlog.h"
using namespace std;
int main()
{
shared_ptr<Blog> blogPtr=make_shared<BlogCSDN>("YHSBLOG");
shared_ptr<Observer> observerPtr1=make_shared<ObserverBlog>("observer1", blogPtr);
shared_ptr<Observer> observerPtr2=make_shared<ObserverBlog>("observer2", blogPtr);
blogPtr->Attach(observerPtr1);
blogPtr->Attach(observerPtr2);
blogPtr->SetStatus("RandomForest Introduction");
blogPtr->Notify();
blogPtr->SetStatus("DeepLearning Introduction");
blogPtr->Notify();
return 0;
}
Python代码
文件结构:
—Blog.py
—Observer.py
—main.py
代码如下:
—Blog.py
# -*- coding:utf-8 -*-
from Observer import *
class Blog:
def __init__(self):
self.__observerList = list()
self._status = None
def Attach(self, observer):
self.__observerList.append(observer)
def Detach(self, observer):
self.__observerList.remove(observer)
def Notify(self):
for observer in self.__observerList:
observer.Update()
def SetStatus(self, str):
self._status = str
def GetStatus(self):
return self._status
class BlogCSDN(Blog):
def __init__(self, name):
Blog.__init__(self)
self.__blogName = name
def SetStatus(self, str):
self._status = self.__blogName + " " + str
—Observer.py
# -*- coding:utf-8 -*-
from Blog import *
class Observer:
def Update(self):
pass
class ObserverBlog(Observer):
def __init__(self, name, blog):
self.__observerName = name
self.__blog = blog
def Update(self):
str = self.__observerName + " " + self.__blog.GetStatus()
print str
—main.py
# -*- coding:utf-8 -*-
from Blog import *
from Observer import *
if "__main__" == __name__:
blog = BlogCSDN("YHSBLOG")
observer1 = ObserverBlog("observer1", blog)
observer2 = ObserverBlog("observer2", blog)
blog.Attach(observer1)
blog.Attach(observer2)
blog.SetStatus("RandomForest Introduction")
blog.Notify()
blog.SetStatus("DeepLearning Introduction")
blog.Notify()