亮神知识库 亮神知识库
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)

亮神

前程明亮,未来可期
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)
  • 刷题

  • 杂(待整理)

    • source map深入
    • CI&CD
    • 设计模式
      • 日常开发用到的设计模式
      • Vue用到了哪些设计模式
    • 性能优化
  • 学习

  • 面试

  • 实用技巧

  • 心情杂货

  • 年度总结

  • 友情链接
  • 更多
  • 杂(待整理)
0zcl
2025-06-26
目录

设计模式

# 日常开发用到的设计模式

  1. 单例模式:类有一个返回实例的接口,一个类只有一个实例。
class Single {
  static instance = null
  static getInstance() {
    if (!Single.instance) {
      Single.instance = new Single()
    }
    return Single.instance
  }
}

const a = Single.getInstance()
const b = Single.getInstance()
a === b
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. 策略模式:可以用对象来保存策略和策略方法的映射。比如:如果当前是A角色,就去做对应的处理;不同角色对应不同处理。可以减少大量<code>if-else</code>的使用
const queryConfig = {
  '班主任': func1,
  '教师': func2,
  'xxx': func3
}
queryConfig[type] && queryConfig[type]()
1
2
3
4
5
6
  1. 代理模式:vue对数组的处理;qiankun对js沙箱的隔离
// 在原型链插入代理
const methodsList = ['push', 'pop']

const arrayPrototype = Array.prototype
const proxy = Object.create(arrayPrototype) // 生成代理对象:proxy.__proto__ === arrayPrototype

methodsList.forEach(method => {
  Object.defineProperty(proxy, method, {
    value: () => {
      console.log('excute', method)
      return 'zcl'
    }
  })
})

let arr = new Array([1,2,3,4])
arr.__proto__ = proxy  // 指向代理

arr.push(5) // excute push


// proxy
class ProxySandbox {
  constructor() {
    const fakeWindow = {}
    this.proxy = new Proxy(fakeWindow, {
      get: (target, prop) => {
        return prop in target ? target[prop] : window[prop]
      },
      set: (target, prop, value) => {
        target[prop] = value
        return true
      }
    })
  }
}

let proxy = new ProxySandbox().proxy
proxy.location
proxy['zcl'] = 'zclzcl'
proxy.zcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  1. 发布订阅:
  • eventEmit;
  • vue中队列收集watcher,派发更新时,遍历队列的watcher更新
  1. 观察者模式(了解)

平时没用到,常用发布订阅~

  • 目标对象Subject,观察者Observer
  • Subject需要维护自身的观察者数组observerList,当自身发生变化时,通过调用自身的notify方法,依次通知每一个观察者执行update方法

observer

class Observer {
  constructor(cb) {
    this.cb = cb
  }
  // 目标对象通知时,执行
  update() {
    this.cb()
  }
}

class Subject {
  constructor() {
    this.observerList = [] // 观察者列表
  }
  // 添加观察者
  addObserver(observer) {
    this.observerList.push(observer)
  }
  notify() {
    this.observerList.forEach(ob => {
      ob.update()
    })
  }
}

ob1 = new Observer(() => console.log('i am ob1'))
ob2 = new Observer(() => console.log('i am ob2'))
subject = new Subject()
subject.addObserver(ob1)
subject.addObserver(ob2)
subject.notify()
// i am ob1
// i am ob2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  1. 装饰者模式:AOP函数。动态的给函数添加动能(执行之前或执行之后)
  • 可以用来分离较验输入和业务代码。
submit.beforeValidate(validate)()
1
  1. 适配器模式
  • 接口请求参数的处理,做适配;
  • nextTick适配兼容 MutationObserver, setTimeout, promise
  1. 工厂模式
  • 简单工厂:把对象的创建放到一个工厂类中,通过参数来创建同一类的对象。
class Role {
  constructor(role) {
    this.role = role
  }
}

class SimpleFactory {
  static getInstance(role) {
    switch (role) {
      case 'admin':
        return new Role('管理员')
      case 'developer':
        return new Role('开发者')
      default:
        throw new Error('参数只能为 admin 或 developer')
    }
  }
}

role1 = SimpleFactory.getInstance('admin')
role2 = SimpleFactory.getInstance('developer')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

提示

如果要生成新的对象各类就需要修改getInstance函数,当可选参数 role 变得更多时,那函数getInstance的判断逻辑代码就变得臃肿起来,难以维护。因此不适合创建多种类型的对象

  • 工厂方法:将创建对象的工作推到子类中进行。每种产品由一种工厂子类来创建。

factory

  • 抽象工厂:大项目中使用。先战略放弃~

简单工厂封装了new到底有啥好处?

代码中最好不要到中new对象,如果构造函数参数变化,那么就得改动多处。造成耦合。因此类定义静态方法,抛出new出来的对象。

# Vue用到了哪些设计模式

代理模式,适配器模式,发布订阅模式,策略模式(响应式数据是否数组,对应不同的策略)。。。

观察者模式和发布订阅模式的有什么区别?

  1. 观察者模式,目标对象的列表会收集观察者对象,当目标对象通知更新时,目标对象会遍历观察者对象,执行观察者对象的更新。发布订阅模式:发布者通过中间人--队列,不会直接和订阅者产生联系 (发布订阅,队列收集的是订阅者的更新方法(eventEmit)也可以是观察者(vue响应式))
  2. 观察者模式,实际上目标对象是直接通知观察者的。相比发布订阅,存在耦合

观察者模式 vs 发布订阅模式 (opens new window) 从一道面试题简单谈谈发布订阅和观察者模式 (opens new window) JavaScript设计模式与开发实践 (opens new window):这本书值得一看

编辑 (opens new window)
上次更新: 2025/07/20, 08:30:18
CI&CD
性能优化

← CI&CD 性能优化→

最近更新
01
2024年
07-20
02
2023年
07-20
03
2022年
07-20
更多文章>
Theme by Vdoing | Copyright © 2025-2025 亮神 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式