1 框架
2 定义
定义: 定义一种一对多的关系。当一个对象(目标对象-主题)状态发生变化的时候,通知多个对象(观察者)。
优点:
降低了目标对象与观察者直接的耦合关系,属于抽象耦合。
缺点:
可能会有过多的观察者,通知较慢?????
3 CODE
背景:定义两个观察者去更新显示歌曲的图片和歌词信息。
#pragma once
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Observer;
struct MusicInfo
{
string lyric;
string img;
};
class Subject
{
public:
Subject() = default;
virtual ~Subject() = default;
virtual void addObserver(Observer* ob) = 0;
virtual void removeObserver(Observer* ob) = 0;
virtual void notify() = 0;
};
class Observer
{
public:
Observer() = default;
virtual ~Observer() = default;
virtual void update(const MusicInfo& info) = 0;
};
class Music : public Subject
{
public:
Music() = default;
~Music() override
{
for (auto i : m_observers)
{
delete i;
}
};
virtual void addObserver(Observer* ob) override
{
m_observers.push_back(ob);
}
virtual void removeObserver(Observer* ob) override
{
auto it = find(m_observers.begin(), m_observers.end(), ob);
if (it != m_observers.end())
m_observers.erase(it);
}
virtual void notify() override
{
for (auto& ob : m_observers)
{
ob->update(m_info);
}
}
void setMusicInfo(const MusicInfo& info)
{
m_info = info;
notify();
}
private:
vector<Observer*> m_observers;
MusicInfo m_info;
};
class Qlabel1 : public Observer
{
public:
virtual void update(const MusicInfo& info) override
{
this->text = info.lyric;
cout << "qlabel1 text -- " << this->text << endl;
}
private:
string text;
};
class Qlabel2 : public Observer
{
public:
virtual void update(const MusicInfo& info) override
{
this->img = info.img;
cout << "qlabel2 img -- " << this->img << endl;
}
private:
string img;
};
#include <iostream>
#include "observer.h"
int main()
{
Music* music = new Music();
Qlabel1* l1 = new Qlabel1();
Qlabel2* l2 = new Qlabel2();
music->addObserver(l1);
music->addObserver(l2);
MusicInfo info;
info.img = "img1";
info.lyric = "lyric1";
music->setMusicInfo(info);
info.img = "img2";
info.lyric = "lyric2";
music->setMusicInfo(info);
}
测试输出结果为:
当歌曲信息改变的时候,歌曲对象(目标对象)成功自动通知到两个label观察者