• javascript设计模式-观察者模式


    观察者模式定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。

    UML示意图:

    其中的角色:

        Subject:主题角色把所有对观察考对象保存在一个对象里,每个主题都可以有任何数量的观察者。主题可以增加和删除观察者对象。并提供订阅和解除订阅的方法。

        Observer:在得到主题的通知时更新自己。

    例子:杂志订阅

    主题角色包含一些对象和方法:

    其中subscribers是按照每个类型创建一个数组来存储对应订阅者的一个对象,subscribe()是将对应订阅者添加到相应类型事件的订阅者数组中的方法。unsubscribe()删除订阅者,publish()遍历subscribers中的每个元素,调用他们注册时所提供的方法,type指的是事件的类型,比如出日刊和出月刊。

    var publisher = {
        subscribers:{
            any:[] //type of event : subscribers
        },
        subscribe:function(fn,type){
            type = type ||"any";
            if(typeof this.subscribers[type] ==="undefined"){
                this.subscribers[type] = [];
            }
            this.subsribers[type].push(fn);
        },
        unsubscribe:function(fn,type){
            this.visitSubscribers("unsubscribe",fn,type);
        },
        publish:function(publication,type){
            this.visitSubscribers("publish",publication,type);
        },
        visitSubscribers:function(function,arg,type){
            var pubtype = type || "any",
                 subscribers = this.subscribers[pubtype],
                 i,
                 max = subscribers.length;
            for(i=0 ; i<max ; i++){
                if(action ==="publish"){
                    subscribers[i](arg);
                }else{
                    if(subscribers[i] === arg){
                        subscribers.splice(i,1);
                    }
                }
            }
        }
    };

    下面的函数接受一个对象,通过把上述发布者的方法复制到该对象,将其转化为一个发布者:

    function makePublisher(o){
        var i;
        for(i in publisher){
            if(publisher.hasOwnProperty(i)&&typeof[i] ==="function"){
                o[i]=publisher[i];
            }
        }
        o.subscribers={any:[]};
    }

    paper对象,发布日报和月刊:

    var paper={
        daily:function(){
            this.publish("big news today");
        },
        monthly:function(){
            this.publish("interesting things","monthly");
        }
    };

    将paper构造成发行者:

    makePublisher(paper);

    订阅者joe:

    var joe = {
        drinkCoffee:function(paper){
            console.log("Just read"+paper);
        },
        sundayPreNap:function(monthly){
            console.log("About to fall asleep to read this"+monthly);
        }
    };

    订阅:

    paper.subscribe(joe.drinkCoffee);
    paper.subscribe(joe.sundayPreNap,"monthly");

    触发一些事件:

    paper.daily();
    paper.daily();
    paper.daily();
    paper.monthly();

    输出:

    Just read big news today
    Just read big news today
    Just read big news today
    About to fall asleep reading this interesting things

    这样分离的好处,是paper对象与joe对象是可以改动的,可以添加事件类型,可以添加订阅者的行为。甚至joe也可以成为发布者,在Twitter上发布状态更新:

    makePublisher(joe);
    joe.tweet = function(msg){
        this.publish(msg);
    };

     paper可以收听joe的Twitter,订阅joe的信息,需要提供方法readTweets:

    paper.readTweets = function(tweet){
        console.log("Call big meeting!Someone"+tweet);
    };
    joe.subscribe(paper.readTweets);

    现在,只要joe发出tweet消息,paper就会得到提醒:

    joe.tweet("hated the paper today");

    会输出:

    "Call big meeting!Someone hated the paper today"

    观察者的使用场合是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。

    观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。

  • 相关阅读:
    js 生成随机数
    解决微信浏览器无法使用reload()刷新页面
    js 去除左右空格
    小程序开发入门-第一天
    我的第一个JSP——动态web
    2019-3-6 复制粘贴
    2019-2-19 异常练习
    2019-1-19 object祖宗类的equals重写
    2019-1-15 课堂笔记
    2019-1-15 课后作业
  • 原文地址:https://www.cnblogs.com/linda586586/p/4251263.html
Copyright © 2020-2023  润新知