观察者模式
观察者模式又叫发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听同一个对象的状态变化,当这个被监听的对象状态发生变化 通知所有观察者,观察者更新自己的状态或者触发其他行为
在实际的开发中,通常有其他对象需要监听一个对象的状态变化,并作出响应的业务逻辑,而我们如果把这些对象(观察者)统一由被监听的对象管理, 不得不建立一种依赖关系,这就导致两种对象的耦合度变高,不容易扩展维护,观察者模式会使它们的耦合度降低,让它们都依赖与各自更高层的抽象。
例如在游戏中某个BOSS死亡状态、角色血量变化状态往往触发很多事件,例如通知场景、队友、其他怪物等等
从下面的UML图中我们可以发现每个观察者必须有相同的接口供被监听对象调用,这也是观察者模式的不足,其实每个观察者可以传入一个参数、返回类型相同的 函数指针
使用观察者模式在处理业务逻辑时还需要注意顺序问题,即当被监听者的状态发生变化后依次调用事件时,前后事件触发的逻辑是否有关联等等。
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
class Observer;
class Entity
{
public:
Entity()
{
m_nFlag = 0;
m_vecObserver.clear();
}
virtual ~Entity()
{
}
void Attach(Observer* pObserver)
{
if (nullptr == pObserver)
{
return;
}
m_vecObserver.push_back(pObserver);
}
void detach(Observer* pObserver)
{
if (nullptr == pObserver)
{
return;
}
for (std::vector<Observer*>::iterator it = m_vecObserver.begin();it!= m_vecObserver.end();)
{
if (*it == pObserver)
{
m_vecObserver.erase(it);
break;
}
else
{
++it;
}
}
}
void Notify();
protected:
int m_nFlag;
private:
std::vector<Observer*> m_vecObserver;
};
class Monster : public Entity
{
public:
Monster()
{
}
~Monster()
{
}
void SetDeadFlag()
{
if (IsDead())
{
return;
}
m_nFlag |= 1;
Notify();
}
bool IsDead()
{
// 假设第一位为死亡标记
return m_nFlag & 1;
}
};
class Observer
{
public:
virtual ~Observer()
{
}
virtual void Update()
{
}
};
class DeadObserver : public Observer
{
public:
DeadObserver(Entity* pEntity)
{
m_pEntity = pEntity;
}
virtual void Update()
{
cout << "DeadObserver::Update" << endl;
}
private:
Entity *m_pEntity;
};
void Entity::Notify()
{
for (auto one : m_vecObserver)
{
one->Update();
}
}
int main()
{
{
Monster objMonster;
DeadObserver objDeadObserver(&objMonster);
objMonster.Attach(&objDeadObserver);
objMonster.SetDeadFlag();
}
system("pause");
return 0;
}
输出:
DeadObserver::Update
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <map>
#include <memory>
#include <functional>
using namespace std;
enum EntityEvent
{
E_DEAD = 0,
E_Revive = 1,
};
class Observer;
class Entity
{
public:
Entity()
{
m_nFlag = 0;
m_mapObserver.clear();
}
virtual ~Entity()
{
}
void Attach(Observer* pObserver,EntityEvent eventType)
{
if (nullptr == pObserver)
{
return;
}
m_mapObserver[eventType] = pObserver;
}
void Detach(Observer* pObserver, EntityEvent eventType)
{
if (nullptr == pObserver)
{
return;
}
auto it = m_mapObserver.find(eventType);
if (it == m_mapObserver.end())
{
return;
}
m_mapObserver.erase(it);
}
void Notify(EntityEvent eventType);
protected:
int m_nFlag;
std::map<EntityEvent, Observer*> m_mapObserver;
};
class Monster : public Entity
{
public:
Monster()
{
}
~Monster()
{
}
void SetDeadFlag()
{
if (IsDead())
{
return;
}
m_nFlag |= 1;
Notify(EntityEvent::E_DEAD);
}
bool IsDead()
{
// 假设第一位为死亡标记
return m_nFlag & 1;
}
};
class Observer
{
public:
virtual ~Observer()
{
}
virtual void Update(Entity* pEntity)
{
cout << "Observer::Update" << endl;
for (auto one : m_vecFun)
{
one(pEntity);
}
}
void RegistEvent(std::function<void(Entity*)> fun)
{
m_vecFun.push_back(fun);
}
private:
std::vector<std::function<void(Entity*)>> m_vecFun;
};
class DeadObserver : public Observer
{
public:
DeadObserver()
{
}
virtual void Update(Entity* pEntity)
{
cout << "DeadObserver::Update" << endl;
Observer::Update(pEntity);
}
};
void Entity::Notify(EntityEvent eventType)
{
auto it = m_mapObserver.find(eventType);
if (it == m_mapObserver.end())
{
return;
}
it->second->Update(this);
}
class Area
{
public:
void DeadEntity(Entity* pEntiy)
{
cout << "Area::DeadEntity" << endl;
}
};
class Role
{
public:
void DeadMonster(Entity* pEntiy)
{
cout << "Role::DeadMonster" << endl;
}
};
int main()
{
{
Monster objMonster;
DeadObserver objDeadObserver;
Area objArea;
Role objRole;
objDeadObserver.RegistEvent(std::bind(&Area::DeadEntity, &objArea,std::placeholders::_1));
objDeadObserver.RegistEvent(std::bind(&Role::DeadMonster, &objRole, std::placeholders::_1));
objMonster.Attach(&objDeadObserver, EntityEvent::E_DEAD);
objMonster.SetDeadFlag();
}
system("pause");
return 0;
}
输出:
DeadObserver::Update
Observer::Update
Area::DeadEntity
Role::DeadMonster