java Script 观察者模式

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        <input id="pub1" type="button" value="第一报社" /><input id="text1" type="text" value="" /><br />
        <input id="pub2" type="button" value="第二报社" /><input id="text2" type="text" value="" /><br />
        <input id="pub3" type="button" value="第三报社" /><input id="text3" type="text" value="" /><br />
        <textarea id="sub1" rows="5" cols="30"></textarea>
        <textarea id="sub2" rows="5" cols="30"></textarea>
    </body>
    <script>
        /*观察者模式:当程序中某个对象的状态发生改变的时候,进行实时的通知*/
        //发布者报社  (被观察的对象)
        var Publish = function(name) {
                this.name = name;
                //当发布者的状态发生改变时需要通知那些对象(观察者列表)
                this.subscribers = []; //就是左右的订阅者   需要注意的是此处的每个订阅者 都是函数类型
            }
            //在当前类的原型对象上添加一个发布的方法
        Publish.prototype.deliver = function(news) {
            var publish = this; //因为存在 每个订阅者 可以订阅多个报社的报纸  所以将当前的报社 暂存  传给每个 订阅者
            //此处的this 指的是当前发布实例  并且获取它们的每一个订阅者
            this.subscribers.forEach(function(fn) { //因为每个订阅者都是函数类型

                fn(news, publish); //将发布的消息 给每一个订阅者
            });
            return this; //将当前报社实例返回  就可以链式调用发布消息  实现链式编程
        }

        //订阅者
        //因为每一个订阅者 都是一个函数  所以在函数的原型上扩展一个订阅的方法
        Function.prototype.subscriber = function(publish) { //订阅者订阅哪家的报社?将报社作为参数传入
            //此处的this指代的是当前的订阅者
            var sub = this;
            //获取当前报社下所有的订阅者 
            //some方法是循环遍历数组中的每一对象 并且执行一个函数  如果其中有一个返回true那么整体返回true 如果整体返回false  才返回false
            var alreadyExists = publish.subscribers.some(function(item) { //item  是每一个函数类型的订阅者
                //如果当前订阅者存在于 订阅者的列表中  就无需订阅了
                //if(sub===item){  
                //  return true;
                //结束循环
                //return false; 

                //以上代码的简写
                return sub === item;
            });
            if(!alreadyExists) { //如果当前对象 没有在订阅者列表中  就将其添加到订阅者列表中
                publish.subscribers.push(sub);
            }
            return this; //将当前订阅者返回  实现链式编程
        }

        //创建一个取消订阅的方法
        Function.prototype.unsubscriber = function(publish) {
            var sub = this; //当前的订阅者
            //从当前报社的订阅者列表 将自己删除
            //filter(过滤函数) 循环遍历数组中的每一个元素  并且执行一个函数  如果不匹配 就删除该元素  返回一个新数组
            publish.subscribers = publish.subscribers.filter(function(item) {
                return item !== sub; //当前遍历的元素如果不等同 当前的调用者  如果返回false  就删除该元素
            });
            return this;
        }

        window.onload = function() {
            //实例化三个报社对象
            var pub1 = new Publish("第一报社");
            var pub2 = new Publish("第二报社");
            var pub3 = new Publish("第三报社");
            //实例化2个订阅者对象
            var sub1 = function(news) {
                Q("sub1").innerHTML = arguments[1].name + ":" + news;
            }
            var sub2 = function(news) {
                Q("sub2").innerHTML = arguments[1].name + ":" + news;
            }

            //添加订阅
            sub1.subscriber(pub1).subscriber(pub2).subscriber(pub3);
            sub2.subscriber(pub2).subscriber(pub3);
            //绑定事件
            EventUtil = {
                addHandler: function(element, type, handler) {
                    if(element.addEventListener) {
                        element.addEventListener(type, handler, false);
                    } else if(element.attachEvent) {
                        element.attachEvent("on" + type, handler);
                    }
                },
                removeHandler: function(element, type, handler) {
                    if(element.removeEventListener) {
                        element.removeEventListener(type, handler, false);
                    } else if(element.detachEvent) {
                        element.detachEvent("on" + type, handler);
                    }
                }
            }

            function Q(ele) {
                return document.getElementById(ele);
            }

            EventUtil.addHandler(Q("pub1"), "click", function() {
                pub1.deliver(Q("text1").value);
            });
            EventUtil.addHandler(Q("pub2"), "click", function() {
                pub2.deliver(Q("text2").value);
            });
            EventUtil.addHandler(Q("pub3"), "click", function() {
                pub3.deliver(Q("text3").value);
            });
            sub1.unsubscriber(pub1);
            sub2.subscriber(pub1)
        }
    </script>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值