这是我参与「第四届青训营 」笔记创作活动的第1天
背景
参考:1997年的《模式语言》和 1994年的《设计模式》
分类
- 创建型-如何创建一个对象;
- 结构型-如何灵活的将对象组装成较大的结构;
- 行为型-负责对象间的高效通信和职责划分。
浏览器的设计模式(浏览器API设计模式)
单例模式
定义
全局唯一访问对象,在任意地方访问,都是同一对象。一个地方修改,会反映到另一地方对这个对象的使用。 eg:window。
应用场景
缓存;全局状态管理
实现请求缓存
- 传统思想:用类实现面向对象方式,export一个类
- 用JS实现,可以export方法和初始化好的对象,更简单,更灵活
发布订阅(观察者)模式
定义
是一种订阅机制,在被订阅对象发生变化时通知订阅者
应用场景
系统架构之间的解耦;业务中一些实现模,像邮件;实现用户上线订阅
下例是用发布订阅模式实现用户上线订阅:
- 用户创建
- 用户使用
JS中的设计模式
原型模式
定义
JS中的原型链来实现继承和对象的定义,其中复制已有对象来创建新对象就是原型模式。在JS中常见的基本模式,在其他语言中很少见。
应用
用原型模式创建上线订阅中的用户
- 用户原型及用户的创建
- 用户的使用和观察者模式的使用方式一样
代理模式
定义
可自定义控制对原对象的访问方式或写入方式,并且允许在更新前后做一些额外处理。
应用场景
- 监控:如监控发出所有请求中的成功率,作为一个记录,可以先把fetch封装好,可以拿到返回值作为监控。一般对fetch进行改写代理原本的fetch,每次拿到请求返回是否成功,拿到对应值,发送到监控服务器。
- 代理工具:一般适用于业务场景。
- 前端框架实现:Vue对于数据变化的代理,Dom操作的代理。
使用代理模式实现用户状态的订阅:
online() 函数的缺陷:软件开发单一职责原则:一个方法或一个对象尽量只做一件事。否则重写时不好维护。可以用代理模式进行优化:
实现真正的通知:
迭代器模式
定义
在不暴露数据类型的情况下访问集合中的数据。这里的集合指的是JS中内置的集合:数组[value,...];Map{k1:v1,K2:v2,...};set...
应用场景
用for of 迭代自定义组件结构
模拟Dom结构:
用 for of 迭代所有组件:[Symbol.iterator]()可以让组件变为可迭代的。
测试
前端框架中的设计模式
代理模式
与JS中的API代理模式不同
Vue组件实现计数器:
前端框架对DOM操作的代理:利用虚拟Dom进行代理
Dom更新前后的钩子
组合模式
与迭代器模式相似
定义
可多个对象组合使用成为单个对象,也可单个对象独立使用,Dom的每个节点都可以被渲染。
应用场景
DOM,前端组件,文件目录,部门
- react的组件结构中单个渲染
总结
设计模式重在思想,设计模式不是银弹,不能解决所有问题
- 总结出抽象的模式比较简单,但是想要将抽象的模式套用到场景中非常困难
- 多编程范式带来的更多可能性
- 开源项目学习设计模式并不断实践
练习题 使用组件模式实现一个文件夹结构 - 每个文件夹可以包含文件和文件夹
- 文件有大小
- 可获取每个文件夹下文件的整体大小