Loading... # 前端设计模式及应用 ## 设计模式 - 设计模式就是软件设计中常见问题的方案模型,其具有两个特点: - 从历史经验总结而来 - 与特定语言无关 ### 设计模式的历史 - 最早有关设计模式的书籍:《模式语言:城镇、建筑、建造》1977 - 计算机中的设计模式:《设计模式:可复用面向对象软件的基础》1994 - 直到现在这本书中讲述的23种设计模式仍然是提到设计模式时不可避免谈论的内容 - 在中国,从2014年开始国内互联网大厂异军突起,迅猛发展,设计模式的搜索量激增数倍,后来直至今日设计模式仍然属于比较热门的计算机搜索词汇。 <img src="https://s2.loli.net/2022/07/28/nAwRatzg4Tfk9px.png" alt="image-20220728204854052" width="100%" style=""> ## 浏览器中的设计模式 ### 单例模式 - 定义:单例模式表示全局唯一访问对象,也就是说在应用的各个位置均可以访问到的一个对象,并且访问的对象都是同一个实例。 - 应用场景:缓存,全局状态管理。例如浏览器中window对象就是单例 #### 举个例子 - 使用单例模式实现请求缓存 - 在JavaScript中,使用static关键字定义getInstance函数用于创建对象,如果调用时没有实例就创建一个,有就直接返回,这样保证每次调用返回的都是同一个实例一次性来实现单例模式。 - 将缓存定义在其中,每次请求时先查看缓存中是否有已经请求过的响应,有就直接返回不发送请求,没有再发送真实请求并且将响应结果存进缓存。 <img src="https://s2.loli.net/2022/07/28/dTLQ18ou3wj6qzE.png" width="60%" /> <img src="https://s2.loli.net/2022/07/28/to8I9UGDReWAK6M.png" alt="image-20220728205845138" width="60%" style=""> ### 发布订阅模式 - 定义:一种订阅的机制,可以在订阅对象发生变化时,通知订阅者。 - 应用场景:邮件订阅,好友上限订阅等等。 #### 用户上线订阅举例 <img src="https://s2.loli.net/2022/07/28/8pPcTQdRBg9rf74.png" width="50%" /> <img src="https://s2.loli.net/2022/07/28/zHlQ5VRxrCd3sD8.png" width="70%" /> - 如图一,Notify类型为一个函数,传入一个user表示上线的用户,该函数通知要被通知的用户 - User类存储用户名,用户状态(在线、离线),以及订阅该用户的用户列表,该列表存储订阅该用户的用户对象和通知函数 - 当user1希望订阅user2,则调用user1.subscribe(user2, callUser1); 此函数会在user2的followers中添加user2和通知函数。 - 当user2上线时,首先会将user2的状态设置为在线,同时遍历user2的follower,调用通知函数,此时由user2调用callUser1函数通知user1:user2上线了 ## JavaScript中的设计模式 - 三种:原型模式、代理模式、迭代器模式 ### 原型模式 - 通过复制已存在的对象来创建新的对象 <img src="https://s2.loli.net/2022/07/28/hArifQcJmMeudxK.png" width="67%" /> - 和上一个版本不同,这次版本创建了一个原型用户baseUser用于创建其他用户,通过Object.creat(baseUser)将baseUser复制一份再通过一些操作创建一个新的对象,这就是原型模式 ![image-20220728211801774](https://s2.loli.net/2022/07/28/WrwiMkv6GceYfRH.png) ### 代理模式 - 一般而言,在程序设计开发过程当中,希望做到在一个函数中仅实现一个功能,而在实际开发中很难做到,例如需要监控所有的http请求,在很多位置添加日志,导致很多时候不得不修改业务代码加入这些附属功能。因此出现了代理模式,通过代理的方式添加日志,监控请求,处理副作用。 - 用代理模式将用户上线订阅重写: <img src="https://s2.loli.net/2022/07/28/I3f56sJ7dVkmRAz.png" width="70%" /> ![image-20220728212328301](https://s2.loli.net/2022/07/28/GInksDbcFTJ7Kxm.png) - 在online函数中去除了分发订阅消息的语句,onlion函数仅实现更改用户在线状态,新增了一个创建代理用户的方法在代理中进行消息分发。 - 在createProxyUser函数中利用JavaScript的Proxy对user对象进行代理,劫持对status的更改,当status被改为online时,调用notifyStatusHandlers函数将user上线的消息分发出去。 ## 前端框架中的设计模式 - 代理模式、组合模式 ### 代理模式 - 此处的代理模式与上述JavaScript中的代理模式有所不同 - 在Vue框架中,利用了代理模式进行对DOM树的动态渲染 #### 举个例子 - 在Vue中实现简单的计数器 <img src="https://s2.loli.net/2022/07/28/MXxvUtD4fIjzSCJ.png" width="70%" /> 在点击button的过程中,显示的值会随着点击次数增加而增加,如果打开开发者选项看,可以发现每次点击时仅有最少的元素发生了变化,如何实现的? 如果直接使用innerText或者innerHTML进行修改,则渲染流程是修改DOM属性=>视图更新 而Vue框架中,将整个DOM树代理了,在Vue中修改某个属性是在代理的DOM树上进行修改,而Vue对修改的内容进行检查,将发生变化的部分单独渲染到真正的DOM树上,这是Vue框架中的代理模式。 ### 组合模式 - 可以多个组件组合使用,也可以单个组件独立使用 - 主要体现在React框架中的组合 #### 举个例子 - 定义一个按钮组件: <img src="https://s2.loli.net/2022/07/28/k1s3JSc6DEu7bZO.png" width="70%"/> 在组合中进行使用 <img src="https://s2.loli.net/2022/07/28/Ad9kVolQPL82s6R.png" width="70%"/> 将Count组件与Header组件、Footer组件组合使用,建立一个基本的网页,同时如果其他地方有用到Count组件也可以直接进行组合,这就是React中的组合模式。 ## 总结 - 设计模式不是银弹 - 设计模式并不能解决所有的问题,从业务中抽象出设计模型相对简单,但是想要将设计模型套用在实际的场景中却可能十分困难。 - 现代语言的多编程范式为设计模式提供了无限可能。 - 向优秀的开源项目学习模式设计并不断实践。 Last modification:July 28, 2022 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏
One comment
555