设计模式-观察者模式(行为)、发布订阅模式

1 观察者模式

1.0 需求

两个对象之间存在一种关系:当一个对象的状态变化时,另一个类的状态应该做出相应的变化。

1.1 实现

一个对象变化需要通知另一个对象,轮询是不可能的,只能是显式的通知,也就是说一个对象在状态变化的时候显式的通知另一个对象。显式通知的意思是 调用另一个对象的一个方法。

// 前置声明
class ABChanger;

// 主动观察者基类
// 他会被动的接到通知。
class ABStaff
{
public:
    virtual void update(/*可能的参数*/)=0;
    void attach(ABChanger* );
private:
    ABChanger* Changer;
};

// 具体的不同种类的观察者,对收到的消息做出相应
class Staff1 :public ABStaff
{
    //重写 update 表示对手打通知以后会做出的相应
};

class Staff1 :public ABStaff
{
    //重写 update 表示对手打通知以后会做出的相应
};


// 被观察的对象,当自己状态改变的时候需要通知观察了自己的对象
class ABChanger 
{
public:
    void add(ABStaff* );
    void remove(ABStaff* );
    void update(/*可能的参数*/){
        //遍历 list 调用每个 ABStaff 的 update ,达到通知的目的
    }

private:
    vector<ABStaff*> list;
};



class Changer1:public ABChanger 
{
    //可能不同的 ABChanger
};

  

1.2 理解

感觉观察者模式,改名为通知模式更为贴切,因为是当一个类状态改变的时候,自己主动去通知别人。

2 发布订阅模式

2.0 需求

观察者模式,观察者与被观察者之间强耦合。

而订阅发布模式在进行解耦,中间添加一个Centor

发布者(被观察者)当状态改变的时候向Centor发布消息(发布者调用函数,然后将Centor,和消息传入函数,函数内部又会将消息转发给Centor)。Centor的函数又会遍历、通知所有订阅了该消息的观察者(调用其函数)。

2.1 实现

// 前置声明
class ABCentor;  // 消息中心:收到Publisher,发来的消息就遍历ABStaff调用其update
class Publisher; // 发布消息,调用  ABCentor 的publish
class ABStaff;   // 订阅到 ABCentor,由 ABCentor 调用自己的update

// 主动观察者基类
// 他会被动的接到通知。
class ABStaff
{
  public:
    virtual void update(/*可能的参数*/) = 0;
    void attach(ABCentor *); //订阅相关频道
  private:
    ABCentor *centor;
};

// 具体的不同种类的观察者,对收到的消息做出相应
class Staff1 : public ABStaff
{
    //重写 update 表示对手打通知以后会做出的相应
};

class Staff1 : public ABStaff
{
    //重写 update 表示对手打通知以后会做出的相应
};

// 被观察的对象,当自己状态改变的时候需要通知观察了自己的对象
class ABCentor
{
  public:
    void add(ABStaff *);
    void remove(ABStaff *);
    void publish(Msg)
    {
        //遍历所有的订阅者,调用订阅者的 update();
    }

  private:
    vector<ABStaff *> list;
};

class Centor1 : public ABCentor
{
    //可能不同的 ABCentor
};

// Publisher 也可能存在继承
class Publisher
{
  public:
    // 消息转发给  ABCentor
    void publish(ABCentor *centor, Msg msg)
    {
        centor->publish(msg);
    }
}

  

3 总结

本质上没有区别,只是发布订阅模式,将发布者和订阅者解耦了。

另外,真的这种模式叫做通知模式更好,因为是观察者并没有观察观察者,而是被观察者显式的通知了观察者。

原文地址:https://www.cnblogs.com/perfy576/p/8553890.html