【JavaScript设计模式】-观察者模式 Observe

  • Post author:
  • Post category:java




关系介绍

为方便记忆我将真个模式主要分为三个部分:


发布者

:在执行某个动作后将特定的消息发布到消息池


订阅者

:将订阅的特定消息注册到消息池,并提交一个回调函数,在订阅的消息被触发时,会执行该回调函数,用于接受消息


消息池

:用于存放所有所有订阅者的注册信息并在接受到发布者的消息后触发该消息下的所有回调函数

发布和订阅之间的关系没有先后之分,只要发布的消息在消息池中已经注册过,就会将当前消息类型下存放的回调函数全部执行



观察者模式关系图:



简单实例

// 页面加载后立即执行,使用闭包保证数据持久存在
var Observe = (function(){
    var __messages = {}
    return {
        // 订阅者注册信息接口
        subscribe:function(type,fn){
            // 判断是否有订阅者在列队 数组 中
            if(typeof __messages[type]==='undefined'){ //如果没有
                __messages[type] = [fn]
            }else{ // 如果已经存在相同类型的消息
                __messages[type].push(fn)
            }
        },
        // 发布消息接口
        fire:function(type,args){
            if(!__messages[type]){
                return;
            }
            var events = {
                type:type,
                args:args
            }
            var i = 0
            var len = __messages[type].length
            for (; i < len; i++) {
                __messages[type][i].call(this,events) // 执行当前相同type的订阅消息
            }
        },
        // 移除信息接口
        remove:function(type,fn){ 
            if(__messages[type] instanceof Array){
                var i= __messages[type].length
                for(;i>=0;i--){
                    __messages[type][i]===fn &&__messages[type].splice(i,1) // 从当前消息列队删除订阅
                }
            }
        }
    }
 })();


// 订阅消息
Observe.subscribe('test',function(e){
    console.log(e);
})
var fn = function(e){
    console.log(e);
}
 Observe.subscribe('test1',fn)

 // 发布 ‘test’ 消息
 Observe.fire('test',{msg:'这是传递的参数'});
 Observe.fire('test1',{msg:'这是传递的参数1'});
 // 移除这则订阅消息
 Observe.remove('test1',fn); 
 Observe.fire('test1',{msg:'这是传递的参数1'}); // 发布消息后也不会输出



实际应用场景


查看实例

一个模块即可以是订阅者,也可以是发布者:比如评论板块,当用户提交评论后,评论列表订阅的添加消息会触发从而增加一条展示数据,这时他是一个订阅者,当某一条评论删除的时候,他又作为一个发布者将删除消息发布出去。

观察者模式在实际的项目应用很广泛,比如

vuex

正是使用了该方式,在vue的响应式原理中也起到关键的作用。

贯彻着你是最主要的作用时解决类和对象之间的耦合解耦两个相互依赖的对象,使其依赖于观察者的消息机制。各模块之间只需要通过消息进行通讯,相互之间的修改不会影响到其他模块。


参考链接



版权声明:本文为weixin_40289389原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。