JS设计模式 --- 观察者模式

2022-07-28,,,

JS设计模式观察者模式

又来更新了,昨天学了白贺翔老师的观察者模式,分享一下,直接看代码!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./CommonUtil.js"></script>
</head>
<body>
    <script charset="utf-8">
        // JS观察者模式:对程序中的某一个对象进行实时观察,当该对象发生变化,进行通知
        // 有两个重要的角色:观察者 被观察者

        // 经典案例:订报纸(报社(也叫发布者,被观察者),订阅者(观察者))

        // 发布者 被观察者
        var Publish=function(name){
             this.name=name;
             this.subscribers=[];//接受所有的订阅者(每一个订阅者都是一个函数类型fn)
        };
        // Publish类实例对象发布消息的方法
        Publish.prototype.deliver=function(news){
             var publish=this;//当前实例 当前发布消息的报社
             this.subscribers.forEach(function(fn){//把消息发布给这家报社的所有的订阅者
                    fn(news,publish);
             });
             return this;//链式编程
        };

    //    因为所有的订阅者都是函数类型fn,所以直接在Function的原型上添加方法
        // 订阅者 观察者 具体的一个订阅者去订阅报纸的方法
        Function.prototype.subscriber=function(publish){
                 var sub=this;//取得当前订阅的报纸的这个人
                //  先判断这家报社是否已经存在当前订阅者
                // some方法:循环遍历数组的每一个元素,每一个元素读取执行一个函数,如果其中有一个返回true,那整体就返回true
                var alreadyExists= publish.subscribers.some(function(item){
                        return item === sub;
                    });
                    if(!alreadyExists){ //如果不为真,表明该订阅者没有在这家报社订阅过
                        publish.subscribers.push(this);  //就添加进去
                    }
                    return this;
        };

           // 订阅者 观察者 具体的一个订阅者去取消订阅报纸的方法
           Function.prototype.unsubscriber=function(publish){
                 var sub=this;//取得当前取消订阅的报纸的这个人
                //  先判断当前订阅者是否在这个报社里,如果在,就把他过滤掉
                // filter过滤函数:循环遍历数组的每一个元素,每一个元素读取执行一个函数,如果不匹配就过滤(删除)该元素
                publish.subscribers=publish.subscribers.filter(function(item){
                       return item !== sub;//满足的就返回,不满足的就过滤
                });
                return this;//链式编程 
        };

        window.onload=function(){
        //    实例化发布者对象(报社 被观察者)
        var pub1=new Publish('第一家报社');
        var pub2=new Publish('第二家报社');
        var pub3=new Publish('第三家报社');

        // 观察者 订阅者接收消息
        var sub1=function(news){
              document.getElementById('sub1').innerHTML += arguments[1].name + ":" + news + "\n";
        }; 
        var sub2=function(news){
              document.getElementById('sub2').innerHTML += arguments[1].name + ":" + news + "\n";
        }; 

        // 订阅者订阅报纸 执行方法
        sub1.subscriber(pub1).subscriber(pub2).subscriber(pub3);
        sub2.subscriber(pub1).subscriber(pub2);

        // 事件绑定    BH.EventUtil.addHandler(document.getElementById('pub1'),'click',function(){
            pub1.deliver(document.getElementById('text1').value);
        });
        BH.EventUtil.addHandler(document.getElementById('pub2'),'click',function(){
            pub2.deliver(document.getElementById('text2').value);
        });
        BH.EventUtil.addHandler(document.getElementById('pub3'),'click',function(){
            pub3.deliver(document.getElementById('text3').value);
        });

        // 取消订阅
        sub2.unsubscriber(pub2);

     };



    </script>

    <input type="button" id="pub1" value="第一家报社" /> <input type="text" id="text1" /><br/>
    <input type="button" id="pub2" value="第二家报社" /> <input type="text" id="text2" /><br/>
    <input type="button" id="pub3" value="第三家报社" /> <input type="text" id="text3" /><br/>

    <textarea id="sub1" cols="30" rows="5"></textarea>
    <textarea id="sub2" cols="30" rows="5"></textarea>
    
</body>
</html>

本文地址:https://blog.csdn.net/zz_xiaojun/article/details/109381320

《JS设计模式 --- 观察者模式.doc》

下载本文的Word格式文档,以方便收藏与打印。