第二周 2018-02-10

这周还是学习的心路历程,主要是对观察者模式,订阅-发布模式与自定义事件进行学习。

首先,主要是对两种模式进行对比

观察者模式
思路:

1、分别有三个角色,分别是ObserverListSubjectObserver
2、ObserverList:观察者列表,用于存放观察者对象(下一条的Observer),供主体Subject维护。
3、Observer:观察者对象,存放在列表中待命,用于更新视图,如果接到主体Subject的命令则更新,换句话说就是用来观察Subject什么时候发命令。
4、Subject:主体,个人理解它就是“被观察者对象”,被一群Observer围观奸视,只要一说话(发布notify),各个Observer就会有所动作。具体场景可以联想一下某岛的视频(就在此时舍友的电脑忽然响起:澳门赌场开业啦!!)

从生活中理解观察者模式:
像别的大牛一样,我也举个栗子会比较方便理解。

比如在工作中的时候,大家都在加班干活儿,但是有的人手上的活儿已经做完了,有的人手上还没完,完成了就上报工作,直到所有人都完成了,在老大手上调试完毕没有bug才能离开。

假如你也是在团队里的一个开发者,你已经完成了,这个时候肯定压抑不住想下班的心情。然后你就隔三差五去问老大的进度,你隔壁的小伙伴也完成了,也跟你一样隔三差五的去问。

老大(Subject)觉得烦了,就把你们的QQ号(Observer)加上了,拖进一个分组(ObserverList),然后当所有组员都完成调试好了,就给你们群发消息(Subject.notify),以上就是观察者模式了

下面我贴一下各对象的方法,具体实现在顶部的link可以找到(我只是想练习一下写注释2333)。

ObserverList:

function ObserverList() {
  // 初始化观察者列表
}

/**
  * add
  * 添加方法
  * 用于往 “观察者列表” 添加 “观察者对象”
  * @param  {Object} observer 观察者对象
  */
ObserverList.prototype.add = function( observer ) { 
  // code...
}

/**
  * count
  * 统计方法
  * 获取 “观察者列表” 的长度
  */
ObserverList.prototype.count = function() {
  // code...
}

/**
  * get 
  * 获取 “观察者对象” 方法
  * 通过索引从 “观察者列表” 获取 “观察者对象”
  * @param {Number} index
  */
ObserverList.prototype.get = function( index ) {
  // code...
}

/**
  * indexOf
  * 查找方法
  * 查看 “观察者对象” 在列表中的位置,没有则返回-1
  * @param {Object} observer 观察者对象
  * @param {Number} startIndex 起始索引
  */
ObserverList.prototype.indexOf = function( observer, startIndex ) {
  // code...
}

/**
  * removeAt
  * 删除方法
  * 通过索引删除列表中对应的“观察者对象”
  * @param {Number} index 需要删除的索引
  */
ObserverList.prototype.removeAt = function( index ) {
  // code...
}

Observer:

function Observer() {}
/**
  * update
  * 更新函数 / 发布函数
  * 用于更新视图
  * @param {any} context 更新内容
  */
Observer.prototype.update = function(context) {
  // code...
}

Subject:

/**
  * Subject
  * 主体对象
  * 用于维护观察者列表以及发布更新内容
  */
function Subject() {
  // 初始化观察者列表
}

/**
  * addObserver
  * 添加观察者方法
  * 顾名思义添加“观察者对象”
  * @param {Object} observer 观察者对象
  */
Subject.prototype.addObserver = function( observer ) {
  // code...
}

/**
  * removeObserver
  * 删除对象
  * 删除“观察者对象”
  * @param {Object} observer 观察者对象
  */
Subject.prototype.removeObserver = function( observer ) {
  // code...
}

/**
  * notify
  * 发布消息
  * 向观察者对象发布消息
  * @param {any} context 向Observer.update更新内容。
  */
Subject.prototype.notify = function( context ) {

}

订阅-发布模式
思路:
1、订阅-发布模式就比较简单,有三个基本方法:publishsubscribeunsubscribe,还有一个topicList
2、topicList:用于存放订阅消息的列表。
3、subscribe:用于向topicList注册的方法。
4、publish:用于告诉topicList,然后再发布对应topic消息的方法。
5、unsubscribe:用于告诉topicList,然后再删除对应topic的方法。

从生活中理解订阅-发布模式:
假如你也是在团队里的一个开发者,你已经完成了,这个时候肯定压抑不住想下班的心情。然后你就隔三差五去问老大的进度,你隔壁的小伙伴也完成了,也跟你一样隔三差五的去问。

老大(Subject)觉得烦了,就把你们的QQ号(Observer)加上了。

讲到这里,肯定有很多同学有疑问,这TM跟观察者没区别啊!别着急,这里打断了你们的阅读就是为了引出不一样的地方。

刚刚讲到老大把你们的QQ号(Observer)加上了,就把你们都拉进一个群里,然后当所有组员都完成调试好了,就给你们群发消息(Subject.notify),以上就是订阅-发布模式了

/**
  * PubSub
  * 订阅发布类
  * 用于存放初始化的数据
  */
function PubSub() {
  this.pubsub = {};
  this.topics = {};
  this.subUid = -1;
}

/**
  * publish
  * 用于发布内容
  * @param {string} topic 发布主题(订阅事件的名字)
  * @param {any} args 要发布的内容
  */
PubSub.prototype.publish = function( topic, args ) {
    if ( !topics[topic] ) {
        return false;
    }
    var subscribers = topics[topic],
        len = subscribers ? subscribers.length : 0;
    while (len--) {
        subscribers[len].func( topic, args );
    }
    return this;
};

/**
  * subscribe
  * 用于注册内容
  * @param {string} topic 注册主题(订阅的事件名)
  * @param {function} func 主题需要执行的事件
  */
PubSub.prototype.subscribe = function( topic, func ) {
    if (!topics[topic]) {
        topics[topic] = [];
    }
    var token = ( ++subUid ).toString();
    topics[topic].push({
        token: token,
        func: func
    });
    return token;
};

/**
  * subscribe
  * 删除注册内容
  * @param {string} token 事件的token
  */
PubSub.prototype.unsubscribe = function( token ) {
    for ( var m in topics ) {
        if ( topics[m] ) {
            for ( var i = 0, j = topics[m].length; i < j; i++ ) {
                if ( topics[m][i].token === token ) {
                    topics[m].splice( i, 1 );
                    return token;
                }
            }
        }
    }
    return this;
};

总结一下:
观察者模式订阅-发布模式可以说过程是一样的,因为都是用来监听被观察者事件有没被触发。
也可以说是不一样的,因为观察者模式是一对一的方式,也就是上面的例子,老大发个消息还要群发。而订阅-发布模式更像是广播的形式,就比如上面的例子,创建一个群来发送消息,不管你接到没反正我是发了,你有去看的话也肯定看到了。


讲到这里,自然也是离不开自定义事件了。
自定义事件的设计思想,与订阅发布模式的概念是吻合的。

咳咳,好像有点长了,下周再写吧…

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容

  • 【编者按】本文作者是 BAE 系统公司的软件工程师 Justin Albano。在本篇文章中,作者通过在 Java...
    OneAPM阅读 658评论 0 4
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,856评论 25 707
  • 人生没有过不去的火焰山 只有被火焰山烧死的人 鱼与熊掌不可兼得 那是你钱带的少了 虽然你摸了一把好牌 但是可以把牌...
    尘世素心_青阅读 145评论 0 0
  • 生活可能在不确定的时间里发生意外,即使早已做好准备也不能孑然面对。
    我是好人ll阅读 132评论 0 0