zoukankan      html  css  js  c++  java
  • publish/subscribe(发布/订阅)模式

    这几天看《JavaScript设计模式》看的云里雾里的,设计模式看似是具体的东西,却又抓不住。在想发布/订阅模式的形态时,开启新思路,有所收获。
     
     
     化繁为简分析,倒推分析; 化简为繁,是实际项目。
     
    实际场景
     
    有一个函数,所传参数不同执行结果不同;
    另一个函数,所传参数不同执行结果不同... 有很多参数
     
    正常情况我们会把代码罗列下来,就像积木一样, 这样看起来整个代码比较杂乱,如果函数之间相互调用会更乱,也不易于维护。
     
    有问题就要解决,聪明的前辈们根据现象,思考出从各个维度对代码进行优化,总结出使用频率高的方式方法,也就是设计模式。
     
    设计模式其实是一种形式。
     
     
    基于上述问题解决方法
     
    倒推的方式,先实现后调用
     
     模块功能
     
     定义一个存放函数的对象topics
     把实现不同功能的函数存放到定义的对象里,动态添加对象属性,对象每个属性是存放对应功能函数和其编号
     
    *topics= {
          "topic1":[{token:0, fn}],
          "topic2":[{token:1, fn1}],
          "topic3":[{token:2, fn2}],
          "topic3":[{token:3, fn2}]
         }
     
     
     定义一个全局对象,把处理上述添加对应的执行函数,以及根据参数执行功能函数挂载到这个对象上。
     
     
    // 定义一个全局对象,挂载处理函数事件
     
    let pubsub = {};
     
    // 定义一个立即执行的匿名函数,生成独立的作用域, es6中可以使用{}形成独立的作用域,但是不能传参
    (function (q) {
        let topicObj = {},
            subUid = -1;
     
     
        // 订阅方法,也是添加函数的方法
        // topic是作为动态的属性名, fn是对应的执行函数
        q.subscribe = (topic, fn) =>{
            // 判断topicObj对象中是否有对应的topic属性,如果没有则设置为数组
            if(!topicObj[topic]){
                topicObj[topic] = []
            }
     
     
            // 下标计算,是属性值,所以要转化为字符串
            let token = (++subUid).toString()
     
     
            // 添加到数组中
            topicObj[topic].push({
                token:token,
                fn:fn
            })
     
     
            //console.log( topicObj )
            //return唯一的标识符token,用于删除指定的项
            return token;
        }
     
     
        // 发布方法,也是执行函数
        q.publish = (topic, args)=> {
            if(!topicObj[topic])return;
     
     
            // 获取指定topic属性项,并获取长度
            let subscribes =  topicObj[topic],
                len = subscribes.length;
     
     
            //console.log(--len);
     
     
            // 遍历并执行
            while (len--){
                // 回调函数有2个参数,一个表示属于对像的属性,另一个则是变量,在定义函数的时候要注意
                subscribes[len].fn(topic, args);
            }
            return this;
        }
     
     
        //  删除订阅者,即对象中指定的属性,也就是对应动态添加的函数
         q.delScribe = (token)=>{
            for(let key in topicObj){
                topicObj[key].forEach((item, i)=>{
                    if(item.token===token){
                        topicObj[key].splice(i,1)
                    }
                })
            }
             console.log( topicObj )
             return this;
         }
     
    })(pubsub);
     
     
    //console.log(pubsub);
     
     
    //测试
    let msg = (data)=>{
        // 这里还可以执行其它相关的函数
        console.log('data---',data);
    }
     
     
    pubsub.subscribe('test', msg);
    pubsub.publish('test', '这是数据');
    //pubsub.delScribe('0');
     
    ~~~~匿名函数的使用,也是很有意思的。 不过是不很眼熟, jQuery框架使用的方式
     
    (function(window){
     
    jquery=function(){}   // 相关代码
     
    window.jquery = jquery;
    })(window)
     
    《JavaScript设计模式》之 publish/subscribe(发布/订阅)模式
  • 相关阅读:
    Compiling LIBFFM On OSX 10.9
    Linux shell 脚本入门教程+实例
    Understanding the Bias-Variance Tradeoff
    Learning How To Code Neural Networks
    MXNet设计和实现简介
    数据需求统计常用awk命令
    Deal with relational data using libFM with blocks
    MATLAB 在同一个m文件中写多个独立的功能函数
    Debug 路漫漫-06
    MATLAB 求两个矩阵的 欧氏距离
  • 原文地址:https://www.cnblogs.com/wjh0916/p/10840011.html
Copyright © 2011-2022 走看看