「这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。
前言
相信很多人都会听过观察者模式,因为 vue 的知名度摆在这,哪怕是前端入门的程序员,只要知道 vue 都可能听说过观察者模式。vue 自身也是观察者模式的实践例子。
观察者模式是什么
观察者模式是一种设计模式,他可以根据统一接口 depend, notify 进行解耦(当然名字叫什么都行)。在观察者模式里有两个角色,一个是关注者,一个是被关注者。两者之间相互交流,其他人没有办法插足。关注者进行了 depend 关注这个动作之后,被关注者会将关注者存起来。被关注者可以通知他的关注者,至于执行什么内容,由关注者决定,被关注者只是发出通知。至于被关注者什么时候通知,关注者并不了解,只知道收到通知之后做什么。
特点
- 容易维护。
由于只有两个角色,并且角色之间的分工明确,所以编写代码的时候如果需要添加功能或者修改功能,可以明确的知道该修改什么地方。
- 不够灵活。
虽然是一体两面,这个特点看上去和第一个特点相反。假设一个场景,当系统的交互比较复杂,而且庞大的时候,所关注的变量可能在各个地方都有引用,这时候注册的关注者是数量非常大的,但是我们需要每个地方都马上根据通知整改吗?实际上往往不需要,比如跳了另一个路由,页面正在展示另一个组件,当收到通知的时候,前一个路由其实是不需要马上修改的。可以等到路由再次展示的时候才修改。并且由于关注者是按照代码执行顺序收集的,所以在通知的时候,反而是更靠前的路由先收到通知。所以需要做其他的额外的处理对观察者模式进行优化。
什么时候用
- 全局状态
全局状态就不用多解释了,就是里面的值在多个地方被使用,而且他们是同一个值。需要实现真正的一呼百应。这时候观察者模式可以发挥巨大作用。但是要主要上面所说可能出现的问题。但是其实全局状态范围不一定非得是很大的范围。比如 vue 里面每个实例的数据,都只限于在这个实例的范围,也就是这个组件的范围,那么当这个组件被销毁后或者跳到另一个组件的时候,就不会出现关注过多的情况。
- 在改变一个值需要做很多操作的时候
当有这样一个需求,我们站起来后要先左手要先抬起来,右脚往前迈一步,然后身体左转,右手再捂住嘴巴。我们有一个触发的扳机,并且后面跟着很多操作。那么我们就可以关注站起来,然后左手右脚身体右手去注册自己一会要做的事情。这时候,只要我们一调用站起来,其余的动作就会自己完成。
如果没有观察者模式会怎么办。我们可能会写一个函数,设置一套动作,这个是属于另外一种设计模式了。
function action() {
站起来()
举左手()
跨右脚()
左转()
举右手()
}
复制代码
如何用 JavaScript 实现观察者模式
// 被关注者
class Observer {
constructor() {
this.deps = []
}
depend(dep) {
this.deps.push(dep)
}
notify() {
this.deps.forEach(dep => dep.notify())
}
removeNotify(dep) {
const i = this.deps.indexOf(dep)
if (i > -1) {
this.deps.splice(i, 1)
}
}
}
// 关注者
class Watcher {
constructor(action) {
this.action = action
}
depend(observer) {
this.observer = observer
observer.depend(this)
}
removeDepend() {
if (this.observer) {
this.observer.removeNotify(this)
}
}
notify() {
// 默认操作和自定义操作
this.action()
}
}
复制代码
以上就是观察者模式的一些心得,以后会介绍更多的模式,第一次总结难免有缺陷,但是可以一直迭代,喜欢可以关注这个专栏。