首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

javascript 观察者模式应用

观察者模式应用

上一篇是监听DOM加载完成及改变——MutationObserver[1],实际上是对关于"观察/订阅模式"的一种应用,这次搞定到底什么是“观察者模式”。

在上一篇中对于“观察者模式”的解释概括了一句话:

A想看新闻,A就先在B这'交钱(订阅)',以后有新闻B就给A送报纸,A挑想看的新闻

但是实际上,这句话是比较笼统,并没有完全区分“观察/订阅模式”。

一、观察者模式与订阅模式的区别

首先明确一点,两种模式思路一致,在实现上略有不同。

上图:(在已订阅的前提下)

观察者模式.jpg

发布订阅.png

总结:

结构

在“观察者模式”中,观察者需要“观察”被观察者本身,同理,被观察者在有更改的情况下直接通知观察者,直接关联。

在“发布订阅模式”中,发布者与订阅者都关注“事件/代理通道”,无直接联系

关联性

在“观察者模式”中,因为需要直接关联被观察者,所以声明/使用空间有限。

在“发布订阅模式”中,只需要关联代理通道,可扩展性更强。

执行机制

在“观察者模式”中,大多数情况是同步执行,即被观察者发生改变立即通知观察者。

在“发布订阅模式”中,大多数情况是异步执行,即委托代理通道发布。

二、观察者模式怎么用

上一个粗糙但中二的栗子:

做如图效果,当切换下拉列表时,进行如下操作:

对应按钮激活;

input框写出招式;

下方文字列出说明与随机口诀。

开始搞起:

思路1.0:

大概就是类似情况,所有的业务逻辑都写在一个事件下面, 这本身并没什么问题,但是作为优秀团队的开发写这么高的代码显然有点掉价, 而且不能避免的问题是,如果某些拍脑袋产品告诉你,要更改或添加某些逻辑内容,你要有把握保证不影响其他业务和逻辑。

思路1.5:

既然耦合度高,那么可以利用绑定函数不覆盖的特性,绑定多个事件,

可以,完美分开了,凑合也能看, 然而。。。此时如果要求,只有生效,和不再变动的话,没错,要用解绑,不过,上面的匿名函数要改成声明函数才可以;那如果要再增加两个“观察者”呢,就再复制两个好了。

维护起来有点头疼。

思路2.0:

事件本身很简单,难点看来在/问题,只是按顺序执行,那不如,考虑一下数组?将想要执行的方法到数组中,把选中的值传进去就好了嘛。每当事件触发,就循环执行以下数组里的内容,这样互不影响,添加又方便。

有点意思,删除(解绑)时,就是找到要删除的元素,从数组里移除就好了。查函数名很不科学,如果能多加一个 类似的东西来查找就好了。

那加工一下试试看。

三、观察者模式实现

因为可能会有多个观察者,统一做个类,加个, 加个;

声明

解绑怎么做呢?找就好了。

接下来,有一个问题,如果这时多加一个怎么办,看起来可以效仿写观察者的套路来。(毕竟暴露在外的数组还是很危险的)

被观察者(Subject) - 变动主体,实际上也就是上面声明的

我们需要一个将观察者进去的接口,在这个类里添一个接口。

此时的

接下来是已经写好的退订(解绑),直接粘贴进去(换一个厉害的名字)

最后,是循环执行(发布动态)

每当被观察者(下拉列表)改变时,发布一下

搞定啦。

四、核心思路

关键点:

观察者(参照上面栗子中的button、input、text)

被观察者(参照上面栗子的select)

任务列表(实际上是将栗子中的作为独立存在处理)- 观察者模式与订阅模式的区别点

观察者模式思路

一处内容变更,多处同步修改;

各个内容间本身没有关联;

变更目标单向通信。(双向会不停变动发布,形成死循环)

普通话翻译:"如果我能让变动的下拉列表每变一次就通知一下其他人,又互不影响,就可以了。"

划重点:需要同步更新,且其他内容动态变更,且不需要双向通信的情况

四、观察者模式优劣

优点

一致性。多个观察者关注同一个动作时,做出反应;

低耦合 在上述需求完成后,假设需要再新添一个下拉列表,但是这个下拉列表只需要激活按钮,不需要其他动作, 新建一个被观察者类,按钮组件订阅即可,。

缺点

无法追踪变化 虽然能够依次通知所有观察者,但是观察者无法追踪变化来源,只能单向接收。

限制因素 被观察者不能被观察者影响,否则被观察者会实时变化并发布给观察者,产生无限循环。

性能问题 如果有大量的直接和间接观察者,或者极频繁的变更,会占用更多的时间,有更棒的方案去实现。

记得退订

参考资料

[1]

监听DOM加载完成及改变——MutationObserver:https://juejin.im/post/5d6dd5f3f265da03c23eeff9

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190927A0KI2A00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券