前端应用设计思维提升|青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第6天。今天的由吴老师主讲软件设计模式,本节课就经验总结与软件设计方案进行总结。设计模式的更新迭代非常迅猛,建立合理的代码结构,对前端性能和代码优雅都有很好的改良,下面把所得经验分享给大家!
一、本节课重点内容:
本节课使用了TypeScript例程进行讲解,以请求缓存应用常见为例,
重点讲解了:单例模式
二、课堂知识点纪要:
- 浏览器api设计模式
-
用单例模式实现请求缓存:
单例模式只会定义唯一的访问对象,当函数需要调用时,都是从全局引入同一对象。常用于缓存和全局状态管理
const cache;React: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; } //封装一个异步请求 //请求缓存 eg(“response 2 times”) ,async ()=>{ await request("/user/114514") const start = new Date(); await request("/user/114514") const end = new Date(); const delta = end - start; expect(costTime).toBeLessThan(50); }); -
用发布订阅模式实现请求缓存:
当被订阅对象变化时通知订阅者。常见应用有:邮件系统、动态系统。
type Notice = (user:User) => void; export class User as React.Component<{name:string}>{ name : string; status:"online" | "offline"; fans:{user::User;notice:Notice}[]; constructor( name:string ) this.state={ name = name; status = "offline" fans = [] } subscribe(user:User,notice:Notice){ let tmp = user.state.fans.push({user,notice}) this.setState(state:{fans:tmp}) } online() { this.setState(state:{status:"online"}) this.state.fans.forEach(({notice))=>{ Notice(this); } } } //调用用户上线订阅: eg("notice fans when online",()=>{ const fanA = new User("fanA"); const fanB = new User("fanB") const fanC = new User("fanC") const NotifanA = jest.fn(); fanA.subscribe(fanC,NotifanA) fanC.online(); expect(NotifanA).toBeCalledWith(fanC); }) //效果 A关注了C B不关注 C上线通知A 不通知B 完成童子后 回调给C;
-
- JS代码设计模式
-
原型模式
复制已有对象创建新对象,class类;创建对象时很方便
const firstUser:User{ name :" "; status:"offline"; fans:[]; subscribe(user:User,notice:Notice){ user.fans.push({user,notice}) } online() { this.status = "online"; this.fans.forEach(({notice))=>{ Notice(this); } }, }; export const UserModal = (e:string)=>{ const add:User = Object.create(firstUser); add.name = e; add.fans = []; return add; } //调用api类创建缓存 eg("notice fans when online",()=>{ const fanA = UserModal("fanA"); const fanB = UserModal("fanB") const fanC = UserModal("fanC") const NotifanA = jest.fn(); fanA.subscribe(fanC,NotifanA) fanC.online(); expect(NotifanA).toBeCalledWith(fanC); }) -
代理模式
自定义控制对元的对象访问,并且允许更新前后处理;多用于监控和代理等。
//用户信息卡接口 interface Users{ user:User, status:"online" | "offline"; fans:{user::User;notice:Notice}[]; } export newProxyU =(name:string)=>{ //新增用户 const user = new User(name); //设置代理 const proxyU = new Proxy(user, { set:(target,props:keyof User,value)=>{ target[props] = value; if(props === "status") notify(target,value) } return true; }); //被代理函数命令 const notify = (params:Users)=>{ if(status === "online"){ //调用通知函数 user.fans.forEach({ notice })=>{ Notice(this) } } }; //代理函数回调重置 return proxyU; } -
迭代器
可以实现隐藏数据类型的访问。适用于复杂数据结构的解析,提供通用操作接口。 常见的有数组、列表、树的混用。
const Int = [0,1,2]; = const set = new Set(["0","1","2"]) const Mapy = new Map(); Mapy.set("X","Y");
for(const number of Int){ //... } for(const key of set){ //... } for(const [key,value] of set){ //... }
-
- 框架组合模式:
- 使用框架组合搭建组件时,可以多个对象组和使用,也看可以单个对象独立用;
- 常用于DOM、 组件、 文件目录。
三、实践练习案例:
-
使用React 和for of 实现一基础计数器:
import React from "react"; import {Button} from 'antd'; export function Counter(){ const [count,setCount] = React.useState(0); return( <> <Button onClick={()=>setCount(count:count+1)} count is: {count} </Button> </> ) }
四、参考文献:
- 前端设计应用- 吴立宁 (不可转载)
- 设计模式可复用面向对象软件的基础 设计模式可复用面向对象软件的基础.pdf
五、心得体会:
通过今天的课程,粗浅的学习了软件设计(前端)的五种设计模式,让我对前端的系统理论有了新的认识,觉得自己水平还是优先,需要在日后学习中继续提升!