zoukankan      html  css  js  c++  java
  • 设计模式-观察者模式(行为)、发布订阅模式

    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 总结

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

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

  • 相关阅读:
    SPOJ 1812 Longest Common Substring II(后缀自动机)(LCS2)
    HDU 4441 Queue Sequence(优先队列+Treap树)(2012 Asia Tianjin Regional Contest)
    HDU 4433 locker(DP)(2012 Asia Tianjin Regional Contest)
    HDU 4431 Mahjong(枚举+模拟)(2012 Asia Tianjin Regional Contest)
    NavigationBar的简单设置
    Android如何设置标题栏的高度
    android 在标题栏加上按钮
    MediaRecorder类介绍
    Android ADB server didn't ACK * failed to start daemon * 简单有效的解决方案
    2016/1/7 改 百文百鸡 水仙花数 百马百担
  • 原文地址:https://www.cnblogs.com/perfy576/p/8553890.html
Copyright © 2011-2022 走看看