精华内容
下载资源
问答
  • 本人自己实现的比较完整的发布订阅者模式,不过发布消息时是同步调用。并且在实现过程中使用了单例模式与缺省适配器模式。
  • 小而美的pubsub库,发布订阅者模式
  • 主要介绍了JS模式之简单的订阅者发布者模式,以一个完整实例形式详细分析了JS订阅者发布者模式基本实现技巧,需要的朋友可以参考下
  • 主要介绍了JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法,结合实例形式分析了JavaScript观察者模式概念、原理、使用方法及相关操作注意事项,需要的朋友可以参考下
  • js发布订阅者模式es6实现及其图解

    千次阅读 2019-07-04 13:44:06
    //发布发布, 通知所有主题的所有订阅者更新 pub . publish ( dep1 ) ; //发布发布, 通知所有主题的所有订阅者更新 pub . publish ( dep1 ) ; console . log ( "===========================" ) ; //...

    直接上代码

    
    
    //主题
    class Dep{
      constructor(callback){
        this.subs=[];
        //每个主题更新数据的方法不一样,所以需要传进来
        this.callback=callback;
      }
      addSub(sub){
        this.subs.push(sub);
        return this;
      }
      notify(){
        //通知此主题所有订阅者更新数据
        this.subs.forEach(item=>item.update(this.callback))
      }
    }
    //订阅者(Watcher)
    class Sub{
      constructor(val) {
        this.val=val
      }
      update(callback){
        this.val=callback(this.val);
        //相当于更新视图操作
        console.log(this.val);
      }
    }
    //发布者
    class Pub{
      constructor(){
        this.deps=[];
      }
      addDep(dep){
        this.deps.push(dep)
      }
      removeDep(dep){
        let index=this.deps.indexOf(dep);
        if(index!==-1){
          this.deps.splice(index,1);
          return true
        }else{
          return false
        }
      }
      publish(dep){
      	//发布某个主题的更新
        this.deps.forEach(item=>item == dep && item.notify());
      }
    }
    
    //新建主题, 并向主题中增加订阅者
    let dep1=new Dep(item=>item*item);
    dep1.addSub(new Sub(1)).addSub(new Sub(2)).addSub(new Sub(3));
    //新建发布者, 并向发布者中增加主题
    let pub=new Pub();
    pub.addDep(dep1);
    //发布者发布, 通知所有主题的所有订阅者更新
    pub.publish(dep1);
    //发布者发布, 通知所有主题的所有订阅者更新
    pub.publish(dep1);
    console.log("===========================");
    //新建主题, 并向主题中增加订阅者
    let dep2=new Dep(item=>item+item);
    dep2.addSub(new Sub(1)).addSub(new Sub(2)).addSub(new Sub(3));
    //向发布者中增加主题
    pub.addDep(dep2);
    //发布者发布, 通知所有主题的所有订阅者更新
    pub.publish(dep2);
    //发布者发布, 通知所有主题的所有订阅者更新
    pub.publish(dep2);
    
    //结果
    1
    4
    9
    1
    16
    81
    ===========================
    2
    4
    6
    4
    8
    12
    

    直接上图解
    在这里插入图片描述

    有什么不懂得,直接留言。

    展开全文
  • 主要介绍了C#设计模式订阅发布模式的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
  • vue中发布订阅者模式

    千次阅读 2020-01-13 10:54:07
    https://www.jianshu.com/p/2ec316ca0f8b
    展开全文
  • vue发布订阅者模式$emit、$on

    千次阅读 2019-07-21 11:19:10
    在vue中自定义事件,就是用了发布订阅者模式,vm.$on通过自定义事件,事先订阅一件事,vm.$emit通过自定义事件发布消息,vm.$on会接收到。非父子组件数据传递,通常会用到这两个方法: 下边我们先来用js实现发布...

        家住南京的李先生,最近看上了一套房子,到了售楼处才发现,该楼盘放在早已售罄。好在售楼处工作人员王女士出于好心告知李先生,不久之后还会有一些尾盘推出,开发商在办理相关手续,手续办理好之后便可购买。但到底什么时候能办理好,目前无人知道。于是李先生记下了售楼处电话,每天都会打电话询问是否到了购买时间。除了李先生,还有它的朋友、七大姑八大姨也会每天定点咨询这个问题。一周之后,售楼处王女士决定辞职,原因厌倦了每天回答1000个相同内容的电话。。。

            当然,现实中没有那么愚蠢的销售公司,实际上故事是这样的:李先生把他的电话号码留给售楼处,售楼处工作人员答应他,新楼盘一推出会马上通知李先生,他的朋友及七大姑也把电话号码留在了售楼处,新楼盘一推出工作人员会翻开电话簿,依次遍历上边的电话号码,发送信息告知他们。。。

           在上边案例中,发送短信依次告知 就是一个典型的发布、订阅者模式;李先生和他的朋友及七大姑等购买的人都是订阅者,他们订阅了楼盘开售的消息。售楼处作为发布者,会在适合的时候遍历电话簿上的电话号码,依次给购房者发布消息。

          使用发布订阅者模式有着显著的优点:购房者不需要天天询问开售时间,,在适合的时间点,售楼处会通知这些消息的订阅者;购房者和售楼处之间不再强耦合在一起,只要有新的购房者出现时,只需要把电话号码留在售楼处即可;而售楼处不会关心购房者任何情况,不管购房者 是男 是女 是猪?还是外星人(黑人问号脸)。售楼处的任何变动也不会影响购买者(当然除卷钱跑路的)!只要售楼处记得发短信这件事即可。。。

     

    在vue中自定义事件,就是用了发布订阅者模式,vm.$on通过自定义事件,事先订阅一件事,vm.$emit通过自定义事件发布消息,vm.$on会接收到。非父子组件数据传递,通常会用到这两个方法:

    下边我们先来用js实现发布订阅者模式:(这种模式必须先订阅才能接收到信息,注意顺序!)

    function Center(){
    	//订阅(售楼)中心,把所有要买楼房的人统一放在一个对象里,形成一对多关系
    	//  {"eventName":[callback1,callback2,··· ···]}
    	// 属性eventName:是电话薄
    	// 属性值是一个数组,里边每一个函数就是订阅楼盘信息的人(购房者)
    	this.subscriptionCenter = {};
    }
    //on和emit都是公共方法,所以写在原型上了
    Center.prototype.on = function ( eventName , callback ){
    	if( this.subscriptionCenter[eventName] ){
    		this.subscriptionCenter[eventName].push(callback);
    	}else{
    		this.subscriptionCenter[eventName] = [callback];
    	}
    }
    Center.prototype.emit = function ( eventName , ...publishInfo ){
    	if( this.subscriptionCenter[eventName] ){
    		this.subscriptionCenter[eventName].forEach( cb=>cb( ...publishInfo ) )
    	}
    }
    var center = new Center();
    
    //subscription是电话薄,后边函数是李先生订阅的信息,等待售楼中心发出日期
    center.on("subscription",function MrLi(time){
    	console.log(`您好李先生,新楼盘于${time}开售`)//因为订阅了售楼中心的信息,所以能接收到售楼中心传过来的消息
    })
    //后边函数是李先生的朋友订阅的信息
    center.on("subscription",function friend(time){
    	console.log(`您好李先生的朋友,新楼盘于${time}开售`)
    })
    //后边函数是七大姑订阅的信息
    center.on("subscription",function aunt(time){
    	console.log(`您好七大姑,新楼盘于${time}开售`)
    })
    // 订阅(售楼)中心通过电话薄,给每一个订阅者(购房者)发送消息
    center.emit("subscription","2019年7月21日")

    执行结果:

    建议大家,把代码赋值到编辑器里边,方便查看理解。。。(有不懂得地方欢迎留言询问)

    再来看下vue中$emit用法:

    vm.$emit( "eventName" , [ ... params ] )

    触发当前组件的自定义事件,参数一:自定义事件名,参数二:发送的数据,可以是一个字符串或一个数组,其实在vue源码中,即使你传的是一个字符串参数,还是会转化为数组,只不过在最后自定义事件执行的时候,会使用handler.aplly( context, args)形式把参数传入自定义的方法。(最后我会分析下vm.$emit和vm.$on的源码)

    eg:先看下$emit的用法,在created中使用$on事先监听一个自定义方法,当按钮被点击,$emit这个方法会执行,事件名对应的自定义事件会被触发,也就是$on监听一个自定义方法被触发。

    <template>
      <div>
        <button @click="handleEmit">click</button>
      </div>
    </template>
    
    <script>
    export default {
     created() {
       // this.$on()可为监听的事件,绑定多个处理函数
      this.$on('defaultEvent', this.emitFn1)
     },
     methods: {
       emitFn1(value) {
         console.log(value)// '1'
       },
       handleEmit() {
         this.$emit('defaultEvent', '1')
       }
     }
    };
    </script>

     

    $on用法:事先监听实例上边的自定义事件(也就是监听上边defaultEvent事件),事件由$emit触发,参数二:处理方法,它会接收emit触发的自定义事件的所有参数。

    $emit("eventName",[...params])
    $on("event",function(...params){
    		
    })

    这里就要不举例了,大家可以自己写一写。。。

    源码分析:

    vm.$on

    源码:

    $on方法 是被定义在Vue的原型上,此方法接收2个参数——事件名、事件名对应的处理方法,开始会判断下事件名是否是数组,是数组则循环里边的事件名,依次转化为单个字符串形式,否说明是一个字符串,接下来看下实例中的_events[event]是否有值,有的话,会把处理方法push到数组中;没有值则把值设置为一个数组,再把处理方法push到数组中。

    从上边源码中可分析出:

    (1)vm.$on可绑定多个事件名,前提需要以数组类型定义,多个事件名可对应同一个处理方法。

    (2)实例上会有一个_events对象,对象key为$on绑定的事件名,值为一个数组,数组里边装的是处理方法。

     

    vm.$emit()

    源码:

    $emit方法 定义在Vue的原型上,在源码中只传了一个参数,事件名,为什么呢?先往下看,开始如果是开发环境,把事件名转小写,如果转小写的事件名与传进来的事件名不等 且 实例中的_events对象中有事件名对应的处理方法,会报警告,不会有结果输出,这种情况是定义在$on和$emit中的事件名不一样 或者 子组件触发一个自定义事件名与父组件绑定的自定义事件名不一致,会抛出以上警告。

    继续往下走,根据传进来事件名获取到实例的_events对象中的处理方法,如果有处理方法,掉用toArray方法,把$emit第一个参数(事件名)去掉,只留下参数二(传递的参数)args,并且会把参数二转化为一个数组,toArray方法最后我会介绍,接下来循环cbs数组执行 invokeWithErrorHandling(cbs[i], vm, args, vm, info) 方法,cbs[i]:事件处理方法; ags:传递的参数。

    invokeWithErrorHandling方法:

    invokeWithErrorHandling方法会去判断是否有args参数,有则把参数传到事件处理方法中并执行,没有则只执行事件处理方法。

    补充下:

    还有一种情况是没有$on监听,子组件向父组件传值,使用$emit,在父组件中的自定义标签中绑定子组件触发的自定义事件,触发相对应的函数,这样父组件也会拿到值,原因在于,在子组件created的时候,Vue实例中的_events对像中已经有值了,key:子组件要触发的自定义的事件名,value:对应父组件要触发的事件处理函数。

    export default {
        name:'homeSon',
        created() {
            console.log('son', this._events) // son {handleEmit: Array(1)}
        },
        methods: {
            click() {
                this.$emit('handleEmit', '1') 
            }
        }, 
    }

     

    toArray方法:

    在Vue源码中,单独写了这么一个方法,目的:把类数组(如:arguments)或字符串转化为数组,参数二是起始位,如果传start,会从start位置开始截取,截取到最后,左开右闭,i为循环圈数,ret为数组长度是i,有个小细节,之所以要用new Array 去构造一个数组,原因是可以动态传值,且值就是构造出来的数组长度 。

    展开全文
  • python发布订阅者模式(超简版)

    千次阅读 2019-10-27 23:32:16
    1、生产基类(父类) class BaseProducer(object): ''' 生产 ''' def __init__(self,name): ''' 初始化生产对象 :param name:生产名称 ''' self.name = name self.nu...

    1、生产者基类(父类)

    class BaseProducer(object):
        '''
        生产者
        '''
        def __init__(self,name):
            '''
            初始化生产对象
            :param name:生产名称
            '''
            self.name = name
            self.number = 0
            self.object = None
    
        def action(self):
            '''
            抽象方法:生产方法
            :return:
            '''
            pass
    
        def action(self,number,object):
            '''
            带参的生产方法:根据数量和对象生产不同的产品
            :param number:生产数量
            :param object:生产产品
            :return:
            '''
            self.number = number
            self.object = object
            while number > 0:
                obj = object()
                list.append(obj)
                number -= 1
            return list
    
        def __str__(self):
            '''
            生产者的toString方法
            :return:
            '''
            return "生产名称:"+self.name+"\t生产数量:"+str(self.number)+"\t生产对象:"+str(self.object)

    2、消费者基类(父类)

    class BaseConsumer(object):
        '''
        消费者
        '''
        def __init__(self,name):
            '''
            初始化消费者对象
            :param name:消费者名称
            '''
            self.name = name
    
        def action(self,object):
            '''
            消费者消费动作
            :param object:消费物品
            :return:
            '''
            pass

    3、根据业务模拟编写生产者消费者

    import Queue
    from base_producer import BaseProducer
    from base_consumer import BaseConsumer
    
    
    class WebProducer(BaseProducer):
    
        # def __init__(self,name):
        #     self.name = name
    
        def action(self, number, object):
            '''
            根据数量和对象生产不同的产品
            :param number:生产数量
            :param object:生产产品
            :return:
            '''
            self.number = number
            list = []
            while number > 0:
                obj = object()
                list.append(obj)
                number -= 1
            return list
    
    
    class WebConsumer(BaseConsumer):
    
        def __init__(self, name):
            self.name = name
    
        def action(self, object):
            for i in object:
                # 打印输出生产者
                print(i)
    
    
    class A():
        '''
        用于测试的具体消费类
        '''
        pass
    
    
    if __name__ == '__main__':
        # 定义一个队列对象,用于中间缓存
        queue = Queue.Queue()
        # new 一个生产者
        producer = WebProducer("生产者1")
        # 执行生产动作,放回产品列表
        list = producer.action(10, A)
        print(producer.__str__())
        # 把生产的产品放到队列中
        queue.put(list)
        # new 一个消费者
        consumer = WebConsumer("消费者1")
        # 消费者从队列中消费产品
        list = queue.get()
        print(list)
        if None is not list:
            consumer.action(list)
        else:
            print("No producet consumption for the time being!")

    4、运行结果

    5、总结

    其实发布订阅者模式就是生产者消费者模式,

    区别在于发布订阅者多了一个中间队列,

    生产者生产产品,放到队列中,消费者从队列中取出产品消费。

    展开全文
  • EventBus系列文章: ...在EventBus的学习当中,EventBus是基于发布订阅者模式的消息处理框架。 EventBus is an open-source library for Android and Java using the publisher/subscriber pattern for loose co...
  • 该例子程序是用C++代码编写,实现了发布-订阅者模式;通过该例子可以很好的理解设计模式中的发布-订阅者模式的精髓;
  • 发布订阅模式与观察者模式

    万次阅读 多人点赞 2019-03-29 18:25:12
    设计模式并非是软件开发的专业术语,实际上,“模式”最早诞生于建筑学。 设计模式的定义是:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。通俗一点说,设计模式是在某种场合下对某个问题的一种...
  • JavaScript发布者-订阅者模式

    千次阅读 2019-05-03 20:26:53
    发布者-订阅者模式又称观察者模式:当一个对象(发布者)状态发生改变时,所有依赖它的对象(订阅者)都会得到通知。 该模式广泛应用在异步编程中:我们无需关注对象在异步运行期间的内部状态,只需要订阅感兴趣的...
  • 主要介绍了JavaScript设计模式之观察者模式(发布者-订阅者模式),本文详细的讲解了JavaScript中的观察者模式,需要的朋友可以参考下
  • 主要介绍了Vue发布订阅模式实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • JS中的发布-订阅者模式

    千次阅读 2019-03-13 17:19:43
    vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter, 在数据变动时发布消息给订阅者,触发相应的监听回调。 三、什么是发布-订阅者模式 多个订阅者...
  • C++发布订阅者模式demo

    千次阅读 2018-02-05 16:50:51
    #ifndef _OBSERVER_H_ #define _OBSERVER_H_ #include #include using namespace std; class Msg { public: virtual int GetMsgID() = 0; virtual void* GetMsg() = 0;
  • //监听 $redis = new Redis(); $redis-&gt;connect('127.0.0.1',6380); echo 'reading c1 ...\n'; //设置超时控制 $redis-&gt;setOption(Redis::OPT_READ_TIMEOUT,-1); $redis-&gt;subscribe(['c1...
  • 观察者模式 优点:更加解耦,支持广播通信 缺点:大量观察者,广播有性能问题 举个最简单的例子: 其中body是发布者,回调函数function是观察者。 document.body.onclick = function(){ console.log('我是一个观察...
  • 发布订阅者模式之JAVA实现

    千次阅读 2019-09-24 07:29:30
    发布订阅者模式之JAVA实现 1.发布者接口 package com.shoshana.publishsubscribe;public interface IPublisher<M>...
  • 二 现实中的发布订阅者模式 1.比如小红最近在淘宝网上看上一双鞋子,但是呢 联系到卖家后,才发现这双鞋卖光了,但是小红对这双鞋又非常喜欢,所以呢联系卖家,问卖家什么时候有货,卖家告诉她,要等一个星期后才...
  • Vue双向绑定(数据劫持,发布订阅者模式,diff算法) 最近一段时间自己找点东西学习,因为面试vue双向绑定问的挺多的,就想去深入研究一下本质原理,说是本质也不算,就是看了看别人的研究总结一点自己的看法和理解...
  • 主要介绍了JavaScript设计模式之观察者模式发布订阅模式,结合实例形式详细分析了JavaScript观察者模式发布订阅模式相关概念、原理
  • 发布/订阅者模式 要搞清楚vue中的双向数据绑定原理,就必须理解什么是发布订阅者模式!! 1、首先想好谁是发布者、谁是订阅者(例如NBA专栏就是发布者,NBA球迷就是订阅者) 2、然后给发布者添加一个缓存列表,...
  • 观察者模式又称为发布/订阅(Publish/Subscribe)模式 观察者设计模式涉及到两种角色:主题(Subject)和观察者(Observer) (1)Subject模块 Subjec模块有3个主要操作 addObserver():注册添加观察者(申请订阅...
  • 自己用C++写一个发布订阅者模式

    千次阅读 2019-03-07 22:40:17
    突然想整理一下自己用过的这个模式,半小时写下了这些代码。... observerList,该vector用于存储订阅者对象,当发布者需要发布消息时,消息会被发送给vector中所有的订阅者对象。 在订阅者类中定义...
  • 发布订阅模式

    千次阅读 2020-10-13 16:08:08
    简单的买鞋订阅例子 var shoeObj = {}; shoeObj.list = []; shoeObj.listen = function (key, fn) { if (!this.list[key]) { this.list[key] = []; } this.list[key].push(fn) } shoeObj.notify = function ()...
  • 注意:观察者模式发布订阅模式是有区别的,区别在于观察者模式是由目标进行调度,而发布订阅模式是由独立的调度中心进行调度,可以说发布订阅模式是观察者模式进一步解耦,在实际中被大量运用的一种模式。...
  • 事件是C#中的高级概念,和js中的鼠标点击$("tag...//实例化事件订阅者 //订阅事件 JudgeE.evenClick+=new JudgeE.delegateClick(DoClick.doC); //引发事件 JudgeE.onClick(); Console.ReadKey(); } } }  
  • 发布订阅者模式c++实现

    千次阅读 2011-11-06 20:27:17
    #ifndef BOTTON_H #define BOTTON_H #include #include class BottonListener; class Botton { public:  Botton(const std::string & botton_name);  ~Botton();  const std::string & GetName() ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 106,891
精华内容 42,756
关键字:

发布订阅者模式