设计模式:观察者
试想这样一个场景:小菜老板经常来检查大家工作,但是小菜他们经常上班摸鱼。小菜他们就告诉门口的接待员小美:老板来了就通知他们。小美一旦发现了老板来了,就通知他们所有人开始认真工作了
文章目录
结构图
其中subject类里面主要的函数就是添加观察者和删除观察者以及提醒的函数接口。然后具体的被观察对象(小美),它里面需要有一个观察者的链表,来保存观察者。然后Observer里面需要有有更新消息的接口。
一些思考
其中被观察只需要保存好观察者的指针,只要自己的告知他们的时候,直接调用观察的更新函数即可。
代码
被观察者对象(Subject)
class ISubject {
public:
virtual void attach(IObserve* observer) = 0;
virtual void detach(IObserve* observer) = 0;
virtual void notify() = 0;
};
具体的被观察者 (ConcreteSubject)
class Telltale :public ISubject {
private:
std::list<IObserve*> m_obseverList;
std::string m_message;
public:
virtual void attach(IObserve* observer) override {
m_obseverList.push_back(observer);
};
virtual void detach(IObserve* observer)override {
m_obseverList.remove(observer);
};
virtual void notify() override {
std::list<IObserve*>::iterator iter = m_obseverList.begin();
while (iter != m_obseverList.end()) {
(*iter++)->update(m_message);
}
};
void creatMessage(std::string message = "") {//当传入了新的信息就进行提醒
m_message = message;
notify();
}
};
观察者基类(Observe)
class IObserve {
public:
virtual void update(const std::string& messaageFromSubject) = 0;
};
具体观察者(ConcreteObserve)
class Slacker : public IObserve {
private:
ISubject* m_isubject;
std::string m_messageFromSubject;
std::string m_Name;
public:
Slacker(ISubject* subject,std::string name) : m_isubject(subject) {
m_isubject->attach(this);
m_Name = name;
std::cout << "我是" << m_Name << "记得告诉我老板来了\n";
}
virtual void update(const std::string& messaageFromSubject) override {
m_messageFromSubject = messaageFromSubject;
printInfo();
};
void printInfo() {
std::cout << "当前接收到的信息是:" + m_messageFromSubject << std::endl;
}
void removeFromList() {
m_isubject->detach(this);
std::cout << "从目标除退出订阅信息\n";
}
void setNewSubject(ISubject* subject) {
m_isubject->detach(this);
m_isubject = subject;
std::cout << "设置新的信息订阅目标\n";
}
};
主函数
int main()
{
Telltale xiaomei; //通风报信的小美
Slacker* xiaocai = new Slacker(&xiaomei, "xiaocai"); //摸鱼的小菜
Slacker* daniao = new Slacker(&xiaomei, "daniao"); //摸鱼的大鸟
xiaomei.creatMessage("老板来了"); //老板来了
//xiaocai->printInfo(); //打印当前的信息
//daniao->printInfo();
}
结果
总结
今天解决了小菜摸鱼的问题,真是开心的一天啊。现在本菜要看看leetcode了。