观察者模式
什么是观察者模式
在对象之间定义一种一对多的关系,当某个对象状态改变时,与他存在依赖关系的所有对象都能收到通知并自动进行更新
解决什么问题
当一个对象改变需要通知其他对象,但是不希望与其耦合
优势
解耦合主题接口只依赖于观察者接口,修改时,遵从开闭原则,
弊端
当存在大量观察者对象时将会耗费大量时间通知
被观察者只有在所有观察者通知返回后才能继续执行,任何一个通知都有可能堵塞被观察者对象
当观察者与被观察者如果有循环依赖,可能诱发隐患
示例
enum Event
{
Event_ONE,
Event_TWO
};
class Entity
{
public:
string Name = "111";
};
class Observer
{
public:
virtual ~Observer() {};
virtual void Update(Entity &entity, Event event) {};
};
/*实际代码中应尽量避免继承,而是持有一个subject实例 */
class Subject
{
private:
vector<Observer *> observers;
public:
virtual ~Subject() {};
void AddObserver(Observer *observer)
{
observers.push_back(observer);
}
void RemoveObserver(Observer *observer)
{
for (auto i = observers.begin(); i != observers.end();)
{
if ((*i) == observer)
{
i = observers.erase(i);
}
else
{
i++;
}
}
}
void Update(Entity &entity)
{
Notify(entity, Event_ONE);
}
protected:
//通知状态改变
void Notify(Entity &entity, Event event)
{
for (auto i = observers.begin(); i != observers.end(); ++i)
{
(*i)->Update(entity, event);
}
}
};
class OB1 : public Observer
{
~OB1() override {};
void Update(Entity &entity, Event event) override
{
switch (event)
{
case Event_ONE:
if (entity.Name == "111")
{
cout << entity.Name << "ob1 时间1" << endl;
}
break;
case Event_TWO:
cout << "ob1 Event2" << endl;
break;
default:
break;
}
};
};
class OB2 : public Observer
{
~OB2() override {};
void Update(Entity &entity, Event event) override
{
switch (event)
{
case Event_ONE:
if (entity.Name == "111")
{
cout << "ob2 Event1" << endl;
}
break;
case Event_TWO:
cout << "ob2 Event2" << endl;
break;
default:
break;
}
};
};
int main()
{
Subject *sub = new Subject();
OB1 *ob1 = new OB1();
OB2 *ob2 = new OB2();
Entity entity;
sub->AddObserver(ob1);
sub->AddObserver(ob2);
sub->Update(entity);
sub->RemoveObserver(ob1);
cout << "---------------" << endl;
sub->Update(entity);
}
销毁观察者和被观察者
当观察者销毁时,被观察者依然持有观察者对对象的指针,此时观察者持有了一个被删除内存的指针,观察者在自身析构函数内进行remove
当被观察者销毁时,可以发送一个析构通知,让观察者自身去进行相应处理