一、UML图
二、包含的角色
ISubject类,抽象通知者,一般用一个抽象类 或者接口实现。用来增加观察者, 移除观察者,通知
IObserver类,抽象观察者,为所有具体观察者定义一个接 口,在得到主题的通知时更新自己 这个接口 叫更新接口
Subject类,具体通知者,将有关状态存入具体观察者对象, 在具体通知者的内部状态改变时,给所有登记过的观察者发送通知
Observer类,具体观察者类,实现抽象观察者角色所要求的更新接口,以便使本身的状态与通知者状态相协调
三、特点
当你使用图形用户界面类时通常会遇到一个问题。 比如, 你创建了自定义按钮类并允许客户端在按钮中注入自定义代码, 这样当用户按下按钮时就会触发这些代码。
观察者模式允许任何实现了通知者接口的对象通知者对象的事件通知。 你可在按钮中添加订阅机制, 允许客户端通过自定义订阅类注入自定义代码。
订阅列表是动态的, 因此订阅者可随时加入或离开该列表
观察者通常需要一些上下文信息来正确地处理更新。 因此, 通知者通常会将一些上下文数据作为通知方法的参数进行传递。 通知者也可将自身作为参数进行传递, 使观察者直接获取所需的数据。
四、代码实现
ISubject类
#pragma once
#include "IObserver.h"
#include <list>
class ISubject
{
public:
ISubject() {}
virtual ~ISubject(){};
virtual void Attach(IObserver *observer)
{
list_observer_.push_back(observer);
}
virtual void Detach(IObserver *observer)
{
list_observer_.remove(observer);
}
protected:
virtual void Notify()
{
std::list<IObserver *>::iterator iterator = list_observer_.begin();
while (iterator != list_observer_.end())
{
(*iterator)->Update();
++iterator;
}
}
private:
std::list<IObserver *> list_observer_;
};
IObserver类
#pragma once
#include <string>
class IObserver {
public:
virtual ~IObserver(){};
virtual void Update() = 0;
};
Subject类
#pragma once
#include "IObserver.h"
#include "ISubject.h"
#include <iostream>
#include <list>
#include <string>
/**
* The Subject owns some important state and notifies observers when the state
* changes.
*/
class Subject : public ISubject
{
public:
virtual ~Subject()
{
std::cout << "Goodbye, I was the Subject.\n";
}
std::string state()
{
return subject_state_;
}
void set_state(std::string state)
{
subject_state_ = state;
Notify();
}
private:
std::string subject_state_;
};
Observer类
#pragma once
#include "IObserver.h"
#include "Subject.h"
#include <iostream>
#include <list>
#include <string>
class Observer : public IObserver
{
public:
Observer(Subject &subject, std::string name) : subject_(subject), name_(name)
{
this->subject_.Attach(this);
}
virtual ~Observer()
{
std::cout << "Goodbye, I was the Observer \"" << this->name_ << "\".\n";
}
void Update() override
{
observer_state_ = subject_.state();
std::cout << "Observer: " << name_ << ", its new state is: " << observer_state_ <<std::endl;
}
void RemoveMeFromTheList()
{
subject_.Detach(this);
std::cout << "Observer \"" << name_ << "\" removed from the list.\n";
}
private:
std::string name_;
Subject &subject_;
std::string observer_state_;
};
main
#include "Observer.h"
#include "Subject.h"
int main()
{
Subject *subject = new Subject;
Observer *observer1 = new Observer(*subject, "1");
Observer *observer2 = new Observer(*subject, "2");
Observer *observer3 = new Observer(*subject, "3");
Observer *observer4;
Observer *observer5;
subject->set_state("state A");
observer1->RemoveMeFromTheList();
subject->set_state("state B");
observer2->RemoveMeFromTheList();
subject->set_state("state C");
observer3->RemoveMeFromTheList();
observer4 = new Observer(*subject, "4");
observer5 = new Observer(*subject, "5");
subject->set_state("state D");
observer4->RemoveMeFromTheList();
observer5->RemoveMeFromTheList();
delete observer5;
delete observer4;
delete observer3;
delete observer2;
delete observer1;
delete subject;
return 0;
}