观察者模式

观察者模式

最近重温的一部电视剧《李狗嗨》,是日剧,内容大概是律师处理案子。里面的第二部有一条主线,是审判一个民众都认为应该死亡的一个女人,因为这个女人靠男人过成富豪。最后的结局当然是......但是当审判长锤下的那一刻,最忙的反而是一些记者、写手等等,因为为了抢速度发行报纸和新闻播报等等。其实这个法庭可视为观察者模式,法官是被观察者,当被观察者做出判决的时候,观察者纷纷做出了自己的状态变化,并且去执行自己应该执行的操作。因此观察者模式就是,一对多的对象对应关系,当这个被观察者发生状态变化的时候,一系列的观察都会进行状态变化并且可能还需要执行一些操作。

 

Subject类:所有被观察的共同类,拥有的是观察者列表、然后进行添加和删除观察者的方法、一个用于刷新所有观察者对象状态的方法+各种实际方法

ConcreteSubject:具体被观察者,每个不同的被观察发生相同的状态变化的时候,所引起其观察者状态变化是不同的。不然法庭中的审判长判决和律师进行辩护,所引起的相同观察者,其变化也是不同的。

Observer:观察者抽象类,拥有的是一些共有等功能方法接口、数据,如状态更新等等

ConcreteObserver:具体类,去具体实现每个观察者状态变化时可能进行的数据变化、行为操作等等

 

使用场景:

  • 一对多的关系网中,一个对象变化,随之变化的对象不知道具体多少个的时候
  • 需要一种链式触发的时候。比如审判-报纸-政府反应等等
  • 对象变化必须通知一些未知对象
  • 当A依赖于B,并且需要分开来进行拓展的时候

优点:

  • 耦合度降低
  • 建立了一套触发机制,和反射相似。

缺点:

  1. 通知的时候,需要观察者队列进行通知,如果队列过长,可能导致时间上的误差
  2. 当观察者过多的时候,容易写着了环形的互相触发机制
  3. 不知道观察类怎么变化,只能知道它变化了

 

实操

 

思维:

  1. 观察者,在代码中是被调用者,所以选择先定义,而内容就是状态变化,然后在这个方法接口中调用自己的方法完成行为执行
  2. 先写抽象的Observer,然后去完成具体的类ConcreteObserver
  3. 完成CSomThing类,其中含有观察者列表、删除和添加接口、循环通知观察者接口、共同的方法接口
  4. 实现法官类,具体实现需要实现的方法,我这里是进行判决,然后进行循环通知观察者。其实也可以自定义循环逻辑,添加参数进行判断等等
// ObserverModel.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <vector>
using namespace std;

//抽象观察者,观察者所具备的一些功能
class CNewsPerson
{
public:
    virtual void updateNews() {}
};
//具体观察者,去实现功能,
//就像等待审判的人有记者是网络写手、纸质写手等等。
class CPaperPerson:public CNewsPerson
{
public:
    void updateNews()
    {
        cout << "今天的判审结果是“无罪”,明天的头条有了。" << endl;
    }
};

//一些具体的事情或者变化,比如审判长,下面应该有很多人记者、涉案人员、律师等等
class CSomeThing
{
private:
    //人员集中
    vector<CNewsPerson*> m_vecPerson;
public:
    //添加和删除人员
    void addNewsPerson(CNewsPerson* person)
    {
        m_vecPerson.push_back(person);
    }
    void deleteNewsPerson(CNewsPerson* person)
    {
        //m_vecPerson.remove(person);
        //删除观察者
    }

    virtual void toDoSomething() {}
    //循环遍历观察者
    void toUpdate()
    {
        for (int i = 0; i < m_vecPerson.size(); ++i)
        {
            if (m_vecPerson[i])
                m_vecPerson[i]->updateNews();
        }
    }
};

//审判长的审判定锤会让很多人的状态变化,去执行需要执行的操作
//如记者会快速写文章抓第一条信息等等
//而在实际中,可能会自己重写一些遍历或者添加一些条件来进行不同
//人员对同一个事务变化而会执行的不同操作
class CJudge :public CSomeThing
{
public:
    void toDoSomething()
    {
        cout << "这个案子的判决是:无罪." << endl;
        toUpdate();
    }
};

int main()
{
    CSomeThing *thing = new CJudge();
    CNewsPerson *person = new CPaperPerson();
    thing->addNewsPerson(person);
    thing->toDoSomething();
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值