码迷,mamicode.com
首页 > Web开发 > 详细

js实现观察者模式

时间:2016-08-11 17:36:50      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

  观察者模式:设计该模式背后的主要动力是促进形成松散耦合。在这种模式中,并不是一个对象调用另一个对象的方法,而是一个对象订阅另一个对象的特定活动并在状态改变后获得通知。订阅者也称为观察者,而补观察的对象称为发布者或主题。当发生了一个重要的事件时,发布者将会通知(调用)所有订阅者并且可能经常以事件对象的形式传递消息。

  思路:发布者对象需要一个数组类型的属性,以存储所有的订阅者。订阅(即注册)行为就是将新的订阅者加入到这个数组中去,则注销即是从这个数组中删除某个订阅者。此外,发布消息,就是循环遍历订阅者列表并通知他们。

  

  这里我的大体思路是对的,但是在发布者之外定义了一个新的类即订阅者。在订阅者中定义了一个方法getNews以便在发布者发布消息时调用该方法。然后面试官说这样太麻烦了,万一订阅者没有这个方法呢?然后我不是很懂……于是在发布消息时直接传递了参数:obj.news = msg; 然后面试官说这样不是更麻烦了吗?这样的话如果订阅者没有news这个属性怎么办?还得判断订阅者是否有news这个属性,没有的话就会出现undifined的报错。然后我就不知道该怎么做了……然后面试官为人特别nice,告诉我说可以用继承,或者是在注册时候就传入一个function。

 

下来后上网查相关,注意点如下:

  1. 发送消息即通知,意味着调用订阅者对象的某个方法。故当用户订阅信息时,该订阅者需要向paper的subscribe()提供它的其中一个方法。--------这应该就是面试官所说的注册时候就传入一个方法。

  2. 发布对象paper需要具有以下成员:

    a、 subscribers:一个数组,存储订阅者

    b、 subscribe():注册/订阅,将订阅者添加到subscribers数组中

    c、 unsubscribe(): 取消订阅。从subscribers数组中删除订阅者

    d、 publish() 循环遍历subscribers数组中的每一个元素,并且调用他们注册时所提供的方法

    所有这三种方法都需要一个type参数,因为发布者可能触发多个事件(比如同时发布一本杂志和一份报纸)而用户可能仅选择订阅其中一种,而不是另外一种。

  3、

 

 

首先看的这一篇文章……http://www.2cto.com/kf/201210/163500.html。没看明白。写的代码如下:

 1         //由于这些成员对于任何发布者对象都是通用的,故将它们作为独立对象的一个部分来实现是很有意义的。那样我们可将其复制到任何对象中,并将任意给定对象变成一个发布者。
 2 
 3         //如下实现一个通用发布者
 4 
 5         //定义发布者对象...{}是定义一个对象
 6         var publisher = {
 7             subscribers: {
 8                 any: []         //event type: subscribers
 9             },
10             subscribe: function(fn,type){
11                 type = type || ‘any‘;
12                 if(typeof this.subscribers[type] === "undefined"){
13                     this.subscribers[type] = [];
14                 }
15                 this.subscribers[type].push(fn);
16             },
17             unsubscribe: function(fn,type){
18                 this.visitSubscribers(‘unsubscribe‘, fn, type);
19             },
20             publish: function(publication, type){
21                 this.visitSubscribers(‘publish‘,publication,type);
22             },
23             visitSubscribers:function(action,arg,type){
24                 var pubtype = type ||‘any‘,
25                     subscribers = this.subscribers[pubtype],
26                     i,
27                     max = subscribers.length;
28                 for(i=0;i<max;i++){
29                     if(action == "publish"){
30                         subscribers[i](arg);
31                     } else {
32                         if(subscribers[i] === arg){
33                             subscribers.splice(i,1);
34                         }
35                     }
36                 }
37             }
38         };
39         //定义一个函数makePublisher(),它接受一个对象作为对象,通过把上述通用发布者的方法复制到该对象中,从而将其转换为一个发布者
40         function makePublisher(o){
41             var i;
42             for(i in publisher) {
43                 if(publisher.hasOwnProperty(i) && typeof publisher[i] === "function"){
44                     o[i] = publisher[i];
45                 }
46             }
47             o.subscribers = {any: []};
48         }
49         //实现paper对象
50         var paper = {
51             daily: function(){
52                 this.publish("big news today");
53             },
54             monthly: function(){
55                 this.publish("interesting analysis","monthly");
56             }
57         };
58         //将paper构造成一个发布者
59         makePublisher(paper);
60         //已经有了一个发布者。看看订阅对象joe,该对象有两个方法:
61         var joe = {
62             drinkCoffee: function(paper) {
63                 console.log(‘Just read‘ + paper);
64             },
65             sundayPreNap : function(monthly){
66                 console.log(‘About to fall asleep reading this‘ + monthly);
67             }
68         };
69         //paper注册joe(即joe向paper订阅)
70         paper.subscribe(joe.drinkCoffee);
71         paper.subscribe(joe.sundayPreNap,‘monthly‘);
72         //即joe为默认“any”事件提供了一个可被调用的方法,而另一个可被调用的方法则用于当“monthly”类型的事件发生时的情况。现在让我们来触发一些事件:
73         paper.daily();      //Just readbig news today
74         paper.daily();      //Just readbig news today
75         paper.monthly();    //About to fall asleep reading thisinteresting analysis
76         paper.monthly();    //About to fall asleep reading thisinteresting analysis
77         paper.monthly();

 

js实现观察者模式

标签:

原文地址:http://www.cnblogs.com/haoyijing/p/5761593.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!