设计模式:观察者

设计模式:观察者

试想这样一个场景:小菜老板经常来检查大家工作,但是小菜他们经常上班摸鱼。小菜他们就告诉门口的接待员小美:老板来了就通知他们。小美一旦发现了老板来了,就通知他们所有人开始认真工作了

结构图

在这里插入图片描述

其中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了。

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值