前言
最近c++软件开发过程中,有一个需求可以通过观察者模式来实现,这里复习下观察者模式的原理,并用c++简单实现了这一模式。
一、观察者模式的理解
所谓观察者模式,个人理解就是一个对象的状态(Subject, 即主题)发生变化,许多相关联的对象(Observer, 即观察者)也要发生相应的变化,而且相关联的对象变化是主动发生的,即Subject对象通知Observer对象你要更新你自己了。
这里借用《大话设计模式》一文中的介绍来定义观察者模式:
二、C++实现
上图中具体观察者(ConcreteObserver)依赖具体主题(ConcreteSubject), 我的实现则与之不同:具体观察者(ConcreteObserver)依赖抽象主题(Subject),这符合设计模式中的“依赖倒置原则”。
#include <iostream>
#include <list>
class Subject;
class Observer;
class Observer
{
public:
virtual bool Update() = 0;
virtual ~Observer() {}
};
class Subject
{
private:
std::string state;
std::list<Observer*> notifiedObservers;
public:
const std::string& GetState() const
{
return state;
}
void SetState(const std::string& curState)
{
state = curState;
}
virtual bool Attach(Observer* observer)
{
notifiedObservers.push_back(observer);
return true;
}
virtual bool Detach(Observer* observer)
{
notifiedObservers.remove(observer);
return true;
}
virtual bool Notify()
{
std::list<Observer*>::const_iterator iter = notifiedObservers.begin();
for (; iter != notifiedObservers.end(); iter++)
{
(*iter)->Update();
}
return true;
}
virtual ~Subject() {}
};
class ConcreteSubject : public Subject
{
private:
public:
ConcreteSubject() {}
virtual ~ConcreteSubject()
{}
};
class ConcreteObserver : public Observer
{
private:
Subject* sub;
std::string name;
public:
ConcreteObserver(const std::string& curName, ConcreteSubject* curSub) : name(curName), sub(curSub) {}
virtual bool Update()
{
std::cout << "Notify observer <" << name.c_str() << ">:" << sub->GetState().c_str() << std::endl;
return true;
}
virtual ~ConcreteObserver(){}
};
int main()
{
ConcreteSubject* s = new ConcreteSubject();
ConcreteObserver* observer1 = new ConcreteObserver("Tom", s);
ConcreteObserver* observer2 = new ConcreteObserver("John", s);
s->Attach(observer1);
s->Attach(observer2);
s->SetState("Seriously Warning - Boss comming!");
s->Notify();
delete observer2;
delete observer1;
delete s;
system("pause");
return 0;
}
总结
设计模式真的很有魅力,尤其是将它们用于项目中。但是,对于我们来说,至少对于我来说,能将设计模式用到项目中是很难的,这倒不是说设计模式本身很难理解,真正困难的是怎样能够保证遇到问题时能找到合适的设计模式,有时就是想不到,可能还是理解不到位导致的吧,所以,后面会继续复习其它的设计模式来丰富自己。
参考
《大话设计模式》