持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
授课老师:吴立宁
什么是设计模式
软件设计中常见问题的解决方案模型
- 历史经验的总结
- 与特定语言无关
设计模式背景
-
模式语言:城镇、建筑、建造 (A Pattern Language: Towns, Buildings,Construction) 1977
-
设计模式:可复用面向对象软件的基础 (Design Patterns: Elements of Reusable Object-Oriented Software) 1994
设计模式的趋势
设计模式的分类
23种设计模式
- 创建型 - 如何创建一个对象
- 结构型 - 如何灵活地将对象组装成较大的结构
- 行为型 - 负责对象间的高效通信和职责划分
浏览器中的设计模式
单例模式
全局唯一访问对象,比如JS中的window对象。
应用场景:缓存,全局状态管理。
用单例模式实现请求缓存(typescript语法):
不使用new Request()而是使用静态方法getInstance()
符合单例模式的另外一种场景,在Javascript中可以更加灵活地实现。
import { api } from ” ./utils";
//不同于new XXX,这里直接创建
const cache: Record<string, string> = {};
export const request = async (url: string) = {
if (cache[urL]) {
return cache[urL];
}
const response = await
api(urL);
cache[urL] = response;
return response;
};
发布订阅模式(观察者模式)
一种订阅机制,可在被订阅对象发生变化时通知订阅者。
应用场景
从系统架构之间的解耦,到业务中一些实现模式,像邮件订阅,上线订阅等等,应用广泛。
不仅只是前端,像消息队列,缓存...
用发布订阅模式实现用户上线订阅:
这里的user1和user3可以相互订阅。
Javascript中的设计模式
原型模式
复制已有对象来创建新的对象
应用场景:JS中对象创建的基本模式
用原型模式创建上线订阅中的用户
定义一个原型(可拷贝的)对象User,使用Object.create创建一个baseUser
代理模式
可自定义控制对原对象的访问方式,并且允许在更新前后做一些额外处理
应用场景:监控(比如监控发送请求的成功率),代理工具,前端框架实现(代理DOM操作,数据劫持)等等
使用代理模式实现用户状态订阅
初始模式:online做了许多额外操作。
优化:
创建用户不是new User,而是返回代理后的User。设置处理状态变化的方法。
迭代器模式
在不暴露数据类型的情况下访问集合中的数据
应用场景:数据结构中有多种数据类型,列表,树等,提供通用操作接口
用for of迭代所有的组件。模拟一个DOM树。
测试:
前端框架中的设计模式
Vue或者React框架中的设计模式
代理模式
用Vue组件实现计数器
<template>
<button @click= "count++">count is: {{ count }}</button>
</template>
<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
</script>
为什么count数量增加了,页面会同步渲染?
前端框架中对DOM操作的代理:
原本:更改DOM属性 --> 页面视图更新
实际:更改DOM属性 --> 更新虚拟DOM --DIFF-> 视图更新
组合模式
可多个对象组合使用,可也单个对象独立使用
应用场景:DOM,前端组件,文件目录,部门
总结
设计模式不是银弹,并不难解决所有问题。94年的书籍已经不是不太适合现在。
- 总结出抽象的模式相对比较简单,但是想要将抽象的模式套用到场景中却非常困难。
- 现代编程语言的多编程范式带来更多的可能性。
- 真正优秀的开源项目学习设计模式并不断实践。
纯函数算设计模式?not 编程范式。 纯函数 : 函数可作为参数。
当前的书籍都像传统的设计模式的范例。每个公司都有自己的设计模式。
hook(函数式设计)和composition API(响应式编程设计)是为了更好地复用而产生的。。
JS的类模式,语法糖。适合人类程序员去写的特殊的范式。
MVVM和MVC算代码的设计架构的表现。面向对象的场景,
发布订阅模式有明显的订阅方式,而观察者模式有些区别,比较自动地触发监听对象。