#include <iostream>
#include <set>
#include <string>
using namespace std;
class Subject;
//抽象观察者类
class Observer
{
public:
Observer(string name, Subject* pSubject) :
m_name(name),
m_pSubject(pSubject)
{
}
virtual void Update() = 0;
protected:
string m_name;
Subject* m_pSubject;
};
//抽象通知者类
//抽象通知者类必须要放在具体的观察者类定义之前,否则具体观察者中Subject类成员是无法识别的
class Subject
{
public:
virtual void Attach(Observer*) = 0;
virtual void Detach(Observer*) = 0;
virtual void Notify() = 0;
string m_message = "";
};
//具体观察者
//说话的学生观察者
class TalkStuObserver :public Observer
{
public:
TalkStuObserver(string name, Subject* pSubject) :Observer(name, pSubject) {}
void Update()
{
cout <<m_name<< "收到消息" << m_pSubject->m_message <<endl;
if (m_pSubject->m_message == "老师来了")
{
cout <<"立刻停止讲话,装作认真学习的样子..." << endl;
}
}
};
//玩耍的学生观察者
class PlayStyObserver :public Observer
{
public:
PlayStyObserver(string name, Subject* pSubject) :Observer(name, pSubject) {}
void Update()
{
cout << m_name << "收到消息" << m_pSubject->m_message << endl;
if (m_pSubject->m_message == "老师来了")
{
cout << "立刻停止打闹,装作认真学习的样子" << endl;
}
}
};
//具体的通知者类(好基友)
class GoodFriendSubject :public Subject
{
public:
void Attach(Observer* pObserver)
{
m_observerSet.insert(pObserver);
}
void Detach(Observer* pObserver)
{
if (m_observerSet.find(pObserver) != m_observerSet.end())
{
m_observerSet.erase(pObserver);
}
}
void Notify()
{
for (auto& pObserver : m_observerSet)
{
pObserver->Update();
}
}
private:
set<Observer*> m_observerSet;
};
int main()
{
Subject* pGoodFriend = new GoodFriendSubject();
Observer* pTalkObserver = new TalkStuObserver("张三", pGoodFriend);
Observer* pPlayObserver = new PlayStyObserver("李四", pGoodFriend);
pGoodFriend->m_message = "老师来了";
pGoodFriend->Attach(pTalkObserver);
pGoodFriend->Attach(pPlayObserver);
pGoodFriend->Notify();
cout << "----------------------------" << endl;
pGoodFriend->m_message = "放学了";
pGoodFriend->Notify();
cout << "----------------------------" << endl;
pGoodFriend->Detach(pTalkObserver);
pGoodFriend->m_message = "老师来了";
pGoodFriend->Notify();
system("pause");
return 0;
}
/*
这样实现的观察者模式有一个弊端,那就是统治者通知的所有的观察者必须是同样的功能(同样的函数名),如果是不同的功能,那么是通知不到的,而且还有一个致命的缺点那就是
必须要有一个对象
必须要有一个对象
必须要有一个对象
如果目标想要直接使用一个接口来发出通知,那么是没办法做到的
就像vs当是运行状态的时候,菜单栏中的项就是不一样的,有的状态改变了,有的被隐藏起来的,牵涉到不同的控件
而且这时候没办法让每个控件 去实现一个observer接口,因为这些控件都早已被他们的制作商封装起来了
解决上面出现的问题就需要委托(delegate)<.net中非常好的一项技术>来出马了
委托的使用(c#)
声明委托(delegate关键字)
delegate void EventHandler();
定义委托
event EventHandler update ;
添加委托函数
update += new EventHandler(函数名) //需要注意的是函数必须要和声明中的函数的参数一致和返回值类型一致
这种委托既可以添加类中的成员函数,也可以添加静态函数以及普通函数
*/