• 观察者模式


          最近,小编重新回顾了百度前端大牛张容铭的《JavaScript设计模式》一书,不得不推荐下这本书,因为讲得实在太精彩了,很生动,可谓是书回价值O(∩_∩)O,玩过Angularjs、Reactjs,Redux,了解过RxJS,实现原理都用到观察者模式,可见其重要性,以下便是我的学习总结~

        观察者模式(Observer): 又称为发布-订阅者模式或者消息机制,主要作用是为了解决类或对象之间的耦合,解耦两个相互依赖的对象,使其依赖观察者的消息机制。适用场景比如团队成员用独立闭包模块进行模块开发,为了避免新模块与旧模块的严重耦合,即可采用观察者模式。

    实现思想代码如下,引用自《JavaScript设计模式》一书

     1 var Observer = (function(){
     2     //将消息容器作为静态私有变量存储,是为了防止消息队列暴露而被篡改
     3     var __message = {};
     4     return {
     5         //注册信息接口
     6         regist:function(type,fn){
     7             if(typeof __message[type] === 'undefined'){
     8                 __message[type] = [fn];
     9             }else{
    10                 __message[type].push(fn);
    11             }
    12         },
    13         //发布信息接口
    14         fire:function(type,args){
    15             if(!__message[type])
    16                 return;
    17             var events = {
    18                 type:type,
    19                 args:args || {}
    20             },
    21             i = 0,
    22             len = __message[type].length;
    23             for(;i < len;i++){
    24                 __message[type][i].call(this,events)
    25             }
    26         },
    27         //移除信息接口
    28         remove:function(type,fn){
    29             if(__message[type] instanceof Array){
    30                 var i = __message[type].length - 1;
    31                 for(;i > 0;i--){
    32                     __message[type][i] === fn && __message[type].splice(i,1);
    33                 }
    34             }
    35         }
    36     }
    37 })();
    38 // 注册接口:将订阅者注册的消息推入消息队列中
    39 // 发布接口:当观察者发布一个消息时将所有订阅者订阅的消息一次执行。
    40 // 移除接口:将订阅者注销的消息从消息队列中注销

          笔者室友是一位前端大牛,他的博文中也谈到了观察者模式的JS实现,思想是一样但代码实现有点不一样,于是我借用他的demo改造成自己的实现,代码如下:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 
     4 <head>
     5     <meta charset="UTF-8">
     6     <title>Document</title>
     7 </head>
     8 
     9 <body>
    10     <div class="ez-led" id="clock">00:00:00</div>
    11 
    12     <script type="text/javascript">
    13         var Observer = (function(){
    14             //将消息容器作为静态私有变量存储,是为了防止消息队列暴露而被篡改
    15             var __message = {};
    16             return {
    17                 //注册信息接口
    18                 regist:function(type,fn){
    19                     if(typeof __message[type] === 'undefined'){
    20                         __message[type] = [fn];
    21                     }else{
    22                         __message[type].push(fn);
    23                     }
    24                 },
    25                 //发布信息接口
    26                 fire:function(type,args){
    27                     if(!__message[type])
    28                         return;
    29                     var events = {
    30                         type:type,
    31                         args:args || {}
    32                     },
    33                     i = 0,
    34                     len = __message[type].length;
    35                     for(;i < len;i++){
    36                         __message[type][i].call(this,events)
    37                     }
    38                 },
    39                 //移除信息接口
    40                 remove:function(type,fn){
    41                     if(__message[type] instanceof Array){
    42                         var i = __message[type].length - 1;
    43                         for(;i >= 0;i--){
    44                             __message[type][i] === fn && __message[type].splice(i,1);
    45                         }
    46                     }
    47                 }
    48             }
    49         })();
    50 
    51         window.onload = function() {
    52             var elClock = document.getElementById('clock');
    53             var getTime = function() {
    54                 var _ = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'], //补零
    55                     d = new Date(),
    56                     h = d.getHours(),
    57                     m = d.getMinutes(),
    58                     s = d.getSeconds();
    59                 return [_[h] || h, _[m] || m, _[s] || s].join(":");
    60             }
    61             elClock.textContent = getTime();
    62 
    63             function renderClock(data){
    64                 elClock.textContent = data.args.msg;
    65             }
    66 
    67             //注册渲染时钟消息
    68             Observer.regist('renderClockMessage',renderClock)
    69 
    70             setInterval(function(){
    71                 //每隔1s钟,发布渲染时钟消息
    72                 Observer.fire('renderClockMessage',{msg:getTime()})
    73             },1000)
    74         }
    75     </script>
    76 </body>
    77 </html>

    参考注明:

    1. 百度前端大牛张容铭《JavaScript设计模式》
    2. 优秀室友博文之《JS实现Observable观察者模式》
  • 相关阅读:
    [Leetcode] ZigZag Conversion
    [Leetcode] Wildcard Matching
    [Leetcode] 4Sum
    [Leetcode] Word Break II
    [Leetcode] Best Time to Buy and Sell Stock III
    [Leetcode] Permutation Sequence
    [Leetcode] Surrounded Regions
    [Jobdu] 题目1522:包含min函数的栈
    CUDA2.1-原理之索引与warp
    opencv8-GPU之相似性计算
  • 原文地址:https://www.cnblogs.com/DTBelieve/p/6374310.html
Copyright © 2020-2023  润新知