这是我参与「第四届青训营 」笔记创作活动的第4天
Day4 前端设计模式&应用
何为设计模式?
软件问题常见问题的解决方案模型。
- 历史经验总结
- 与特定语言无关
设计模式背景
思想最重要
1.模式语言:城镇、建筑、建造(1977)
2.设计模式:可复用面向对象软件的基础
设计模式分类
23种设计模式
- 创建型 ——如何创建一个对象
- 结构型——如何灵活的讲对象组装成较大的结构
- 行为型——负责对象之间的高效通信和职责划分
浏览器中的设计模式
单例模式
定义:全局唯一访问对象
应用场景:缓存、全局状态管理等等
实例——单例模式下请求缓存
import {url} from "./utils"
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;
}
发布订阅模式(观察者模式)
定义:一种订阅机制,可在被订阅对象发生变化时通知订阅者。
应用场景:从系统架构之间的解耦,到业务中一些实现模式,像邮件订阅、线上订阅等等,应用广泛。
const button = document.getElementById("button");
const doSomething1 = ()=> {
console.log("Send message to user");
}
const doSomething2 = ()=> {
console.log("log...");
}
button.addEventListener("click",doSomething1);
button.addEventListener("click",doSomething2);
// ...
JavaScript 中的设计模式
- 原型模式
- 代理模式
- 迭代器模式
原型模式
用原型模式创建线上订阅中的用户
const baseUser: User = {
name:"",
status:"offline",
followers:[],
subscribe(user,notify){
user.followers.push({user,notify});
},
online(){
this.status = "online";
this.followers.forEach(({notify})=>{
notify(this);
});
},
}
export const createUser = (name:string) => {
const user:User = Object.create(baseUser);
user.name = name;
user.followers = [];
return user;
}
代理模式
定义:可自定义控制对原对象的访问方式,并且允许在更新前后做一些额外处理
应用场景:监控、代理工具、前端架构实现等等
同样也可以用代理模式实现用户状态订阅
迭代器模拟
定义:在不暴露数据类型的情况下访问集合中的数据
应用场景:数据结构中有多种数据类型:列表、树等,提供通用操作接口。
const numbers = [1,2,3];
const map = new Map();
map.set("k1","v1");
map.set("k2","v2");
conse set = new Set(["1","2","3"]);
for (const [key,value] of map){
//...
}
for (const key of set){
//...
}
实例:用for of迭代所有组件
前端框架中的设计模式
- 代理模式
- 组合模式
代理模式实例 按钮计数器
Vue框架下:
<template>
<button @click = "count++">
Count is :{{count}}
</button>
</template>
<script setup lang = "ts">
import {ref} from "vue";
const count = ref(0);
</script>
前端框架下对DOM操作的处理
更改DOM属性→视图更新
更改DOM属性→更新虚拟DOM→视图更新
组合模式
定义:可以多个对象组合使用,也可以单个对象独立使用
应用场景:DOM,前端组件,文件目录,部门
组合模式实例 React组件结构
export const Count = () =>{
const [count, setCount] = useState(0);
return{
<button onClick = {()=> setCount((count)=>count+1)}>
count is:{count};
</button>
};
};
function App(){
return(
<div ClassName = "App">
<Header />
<Count />
<Footer />
</div>
)
}
总结
设计模式不是银弹
- 总结出抽象的模式相对比较简单,但是想要将抽象的模式套用在实际场景中却非常困难。
- 现代编程语言多编程范式带来的更多可能性
- 通过真正优秀的开源项目学习设计模式并不断实践