聊聊设计模式|字节青训营笔记

87 阅读4分钟

“这是我参与「第四届青训营 」笔记创作活动的第3天

设计模式

设计模式(Design pattern)代表了最佳的实践

  • 历史经验的总结
  • 不受语言的限制

种类

  • 创建型
  • 结构型
  • 行为型

浏览器中的设计模式

  • 单例模式

全局唯一访问对象

全局的状态管理

  1. 单例模式顾名思义保证一个类仅有一个实例,并且提供一个访问它的全局访问点
  2. 好处:
  • 减少不必要的开销
  1. Vue框架中使用的new Vue就使用了单例模式。

Version One

第一种单例模式

  • 不够优雅
  • 不好复用
  • 污染全局
let _instance = null
function getSingle() {
 if(!_instance) {
   _instance = this
 }
 return _instance
}
​
let m1 = getSingle()
let m2 = getSingle()
​
console.log(m1 == m2) // true

其实就是先创建,如果早就存在了,直接使用存在的那一个,如果并不存在,那就创建一个

Version Two

使用闭包创建

let getSingle2 = function (name) {
 this.name = name
}
getSingle2.getInst = (
 function() {
   let _instance
   return function(name) {
     if(!_instance) {
       _instance = new getSingle2(name)
     }
     return _instance
   }
 }
)()
​
let g1 = getSingle2.getInst('丁不三')
let g2 = getSingle2.getInst('丁不四')
console.log(g1 == g2) // true
  • 缺点

代码耦合性太强了我们需要按照单一职责去拆分

Version Three

单例 ==> 符合单一原则 | 对外没有暴露Single 实现更细粒度的划分

const Single = function (name) {
 this.name = name
}
​
Single.prototype.getName = function() {
 return this.name
}
​
const CreateSingle = (function() {
 let _instance = null;
 return function (name) {
   if(_instance) return _instance
   _instance = new Single(name)
   return _instance
 }
})()
​
let v1 = new CreateSingle('得到的');
let v2 = new CreateSingle('ddd');
​
console.log(v1 === v2) // true

Version Four

惰性单例模式调用的时候才会生成实例,其实惰性在前端是一个非常重要的优化手段,就像一些资源懒加载一样,

const CreateSingleV1 = function(fn) {
 let _instance = null;
 return function () {
   return _instance || (_intsance = fn.apply(thisarguments))
 }
}

优点

  • 只有一个实例 ==> 避免了重复的创建销毁占用内存

经常应用在一个弹框或者对于一个用户配置一个购物车的情况

Vuex|mobx比较像

缺点

  • 在动态对象的扩展上比较差

观察者模式

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

优点

  • 观察者和被观察者是抽象耦合的。
  • 建立一套触发机制。

缺点

  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

发布/订阅模式

在很多文章里讲到的观察者模式,其实说的都是发布订阅模式,那么他们的差别到底在哪里呢,让我们一点点往下看。 维基中对于发布/订阅是这样描述的:

发布-订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。

也就是说,发布/订阅模式和观察者最大的差别就在于消息是否通过一个中间类进行转发。

优点

  • 相较于观察者模式,发布/订阅发布者和订阅者的耦合性更低
  • 通过并行操作,消息缓存,基于树或基于网络的路由等技术,发布/订阅提供了比传统的客户端–服务器更好的可扩展性

缺点

  • 当中间类采用定时发布通知时,使用发布订阅无法确定所有订阅者是否都成功收到通知
  • 当负载激增,请求订阅的订阅者数量增加,每个订阅者接收到通知的速度将会变慢

image.png

区别

  • 发布/订阅者相比观察者模式多了一个中间媒介 ==> 发布者和订阅者的关联更为松耦合
  • 观察者模式通常用于同步的场景,而发布/订阅模式大多用于异步场景,例如消息队列。

img


\