前端设计模式及应用|青训营笔记

70 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的第3天

前端设计模式及应用

设计模式

  • 设计模式就是软件设计中常见问题的方案模型,其具有两个特点:
    • 从历史经验总结而来
    • 与特定语言无关

设计模式的历史

  • 最早有关设计模式的书籍:《模式语言:城镇、建筑、建造》1977

  • 计算机中的设计模式:《设计模式:可复用面向对象软件的基础》1994

    • 直到现在这本书中讲述的23种设计模式仍然是提到设计模式时不可避免谈论的内容
  • 在中国,从2014年开始国内互联网大厂异军突起,迅猛发展,设计模式的搜索量激增数倍,后来直至今日设计模式仍然属于比较热门的计算机搜索词汇。

    image-20220728204854052

浏览器中的设计模式

单例模式

  • 定义:单例模式表示全局唯一访问对象,也就是说在应用的各个位置均可以访问到的一个对象,并且访问的对象都是同一个实例。
  • 应用场景:缓存,全局状态管理。例如浏览器中window对象就是单例

举个例子

  • 使用单例模式实现请求缓存

  • 在JavaScript中,使用static关键字定义getInstance函数用于创建对象,如果调用时没有实例就创建一个,有就直接返回,这样保证每次调用返回的都是同一个实例一次性来实现单例模式。

  • 将缓存定义在其中,每次请求时先查看缓存中是否有已经请求过的响应,有就直接返回不发送请求,没有再发送真实请求并且将响应结果存进缓存。

    image-20220728205845138

发布订阅模式

  • 定义:一种订阅的机制,可以在订阅对象发生变化时,通知订阅者。
  • 应用场景:邮件订阅,好友上限订阅等等。

用户上线订阅举例

  • 如图一,Notify类型为一个函数,传入一个user表示上线的用户,该函数通知要被通知的用户

  • User类存储用户名,用户状态(在线、离线),以及订阅该用户的用户列表,该列表存储订阅该用户的用户对象和通知函数

  • 当user1希望订阅user2,则调用user1.subscribe(user2, callUser1);

    此函数会在user2的followers中添加user2和通知函数。

  • 当user2上线时,首先会将user2的状态设置为在线,同时遍历user2的follower,调用通知函数,此时由user2调用callUser1函数通知user1:user2上线了

JavaScript中的设计模式

  • 三种:原型模式、代理模式、迭代器模式

原型模式

  • 通过复制已存在的对象来创建新的对象
  • 和上一个版本不同,这次版本创建了一个原型用户baseUser用于创建其他用户,通过Object.creat(baseUser)将baseUser复制一份再通过一些操作创建一个新的对象,这就是原型模式

    image-20220728211801774

代理模式

  • 一般而言,在程序设计开发过程当中,希望做到在一个函数中仅实现一个功能,而在实际开发中很难做到,例如需要监控所有的http请求,在很多位置添加日志,导致很多时候不得不修改业务代码加入这些附属功能。因此出现了代理模式,通过代理的方式添加日志,监控请求,处理副作用。

  • 用代理模式将用户上线订阅重写:

    image-20220728212328301

  • 在online函数中去除了分发订阅消息的语句,onlion函数仅实现更改用户在线状态,新增了一个创建代理用户的方法在代理中进行消息分发。

  • 在createProxyUser函数中利用JavaScript的Proxy对user对象进行代理,劫持对status的更改,当status被改为online时,调用notifyStatusHandlers函数将user上线的消息分发出去。

前端框架中的设计模式

  • 代理模式、组合模式

代理模式

  • 此处的代理模式与上述JavaScript中的代理模式有所不同
  • 在Vue框架中,利用了代理模式进行对DOM树的动态渲染

举个例子

  • 在Vue中实现简单的计数器

    在点击button的过程中,显示的值会随着点击次数增加而增加,如果打开开发者选项看,可以发现每次点击时仅有最少的元素发生了变化,如何实现的?

    如果直接使用innerText或者innerHTML进行修改,则渲染流程是修改DOM属性=>视图更新

    而Vue框架中,将整个DOM树代理了,在Vue中修改某个属性是在代理的DOM树上进行修改,而Vue对修改的内容进行检查,将发生变化的部分单独渲染到真正的DOM树上,这是Vue框架中的代理模式。

组合模式

  • 可以多个组件组合使用,也可以单个组件独立使用
  • 主要体现在React框架中的组合

举个例子

  • 定义一个按钮组件:

    在组合中进行使用

    将Count组件与Header组件、Footer组件组合使用,建立一个基本的网页,同时如果其他地方有用到Count组件也可以直接进行组合,这就是React中的组合模式。

总结

  • 设计模式不是银弹
  • 设计模式并不能解决所有的问题,从业务中抽象出设计模型相对简单,但是想要将设计模型套用在实际的场景中却可能十分困难。
  • 现代语言的多编程范式为设计模式提供了无限可能。
  • 向优秀的开源项目学习模式设计并不断实践。