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

75 阅读6分钟

设计模式

设计模式是软件设计中常见问题的解决方案模型,它是由历史经验总结的,与特定的语言无关。

设计模式的分类

设计模式一共有23种,主要分为以下三类:

  • 创建型:如何创建一个对象(5种)
    • 单例模式
    • 原型模式
    • 工厂模式
    • 抽象工厂模式
    • 建造者模式
  • 结构型:如何将对象组装成较大的结构(7种)
    • 适配器模式
    • 装饰器模式
    • 桥接模式
    • 代理模式
    • 组合模式
    • 享元模式
    • 外观模式
  • 行为型:负责对象间高效的通信和职责划分(11种)
    • 观察者模式
    • 迭代器模式
    • 策略模式
    • 模板方法模式
    • 职责链模式
    • 命令模式
    • 备忘录模式
    • 状态模式
    • 访问者模式
    • 中介者模式
    • 解释者模式

浏览器中的设计模式

浏览器中常有的设计模式有单例模式发布-订阅模式(又称观察者模式)

单例模式

定义 一个类只有一个实例,并提供一个访问它的全局访问点。我们可以来看一个示例:

如上例所示,通过Singleton.getInstance来创建实例并返回,外部通过Singleton.getInstance()来获取实例,使得只有一个实例,通过比较可知obj1和obj2是同一实例。因此,obj1 === obj2 返回true。结果如下所示:

image.png

单例模式的优缺点 单例模式的优点是单例模式划分了命名空间,减少了全局变量。同时也增加了代码的模块性,将代码组织到了单一的全局变量名下,放置在了单一位置,便于维护。另外,只实例化了一次,便于我们的调试与维护。缺点是违反了设计模式的单一职责原则,一个类应该只关心内部逻辑,不应该关注外部表现。同时,单例模式只提供了单一访问点,有可能导致模块间的强耦合,不利于单元测试。

单例模式的应用场景

  • 缓存
  • 全局状态管理(vuex和redux等)
发布-订阅模式

发布-订阅模式又称观察者模式。它定义了对象之间1对N的关系。当一个对象发生变化时,依赖于该对象上的所有对象都会收到通知。发布订阅模式已经应用于很多场景中,如当我们给DOM绑定一个事件时就已经使用了发布订阅模式。接下来我们可以看以下例子:

如上所示,上例实现了用户的及上线的商品的预定,当商品上架后,系统会给相关的用户发送商品上架提醒。同时,用户也可以在商品商家之前取消预定,我们将相关预定信息删除,商品上架后不再,向用户发送通知。结果如下: image.png 发布订阅模式优缺点发布订阅模式的优点是观察者和被观察者之间是抽象耦合的,可以进行单独扩展和重用且互不影响。另外,支持简单点的广播通信,自动通知所有已订阅的对象。缺点是当订阅者过多时,同时通知多个订阅者会造成性能问题。另外,发布订阅模式无法告知订阅者被订阅目标是怎么变化的,订阅者只知道他变化了。

JavaScript中的设计模式

JavaScript中常用的设计模式有原型模式,代理模式和迭代器模式。

原型模式

原型模式是指通过复制已有对象,来创建新的对象。具体实例如下:

如上例所示,我们定义了一个user对象,并且通过Object.create()来复制新的对象newuser。之后,给newuser赋新值得到一个全新的对象。结果如下:

image.png

原型模式优缺点原型模式的优点是不再依赖构造函数或者类来创建对象,可以将一个对象作为模板对象来创建更多的对象。缺点是对于包含引用类型值的属性来说,所有实例在默认情况下都会取得相同的属性值。

代理模式

代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要时,提供一个替身对象来控制客户访问。客户访问得是替身对象,替身对象接收访问请求后进行指定得处理后,将请求转发给目标对象。

实例

如上所示,小明相送一束花给小美,但由于自己比较内向,不太敢当面去送花。幸好,小明和小美有一个共同好友叫小红。所以,内向的小明决定由小红代替自己完成这件事。

应用场景

  • html元素的事件代理
  • es6的proxy()
  • jquery.proxy()
  • 前端框架的实现

代理模式优缺点代理模式的优点是职责清晰,高扩展性和智能化。缺点是当对象和对象之间添加代理时会影响事件的处理进度。同时,实现代理需要做额外的处理,有的代理会非常复杂。

迭代器模式

迭代器模式指提供一个方法顺序访问一个聚合对象中的每一元素,但不暴露该对象的内部。

实例

如上所示,通过迭代器模式顺序遍历了数组对象中的各种元素。

应用场景

  • Array.prototype.forEach
  • jQuery里的$.each()
  • ES6 Iterator

前端框架中的设计模式

前端框架的设计模式主要有代理模式组合模式两种。代理模式前面已经讲过,他在前端框架的主要应用场景对DOM操作进行代理

组合模式

组合模式是由多个子对象构建出更大的对象,而这些子对象可以是单独的对象,也可以是由子孙对象组合而成的对象。组合模式将对象组合成树形结构,以表示"整体-部分"的层次结构。另外,组合模式通过多态表现,使用户对单独对象和组合对象的使用具有一致性。 实例

如上例所示,我们定义了一个文件夹类和一个文件类。我们可以利用这两个类分别创建文件夹和文件实例,创建完成后,可以把文件加入文件夹当中,也可以把文件夹加入到文件夹中,这样我们就构建出了一颗文件夹树,我们可以利用它实现文件夹扫描以及文件夹大小求值。

应用场景

  • DOM
  • 前端框架组件
  • 文件目录
  • 部门

组合模式优缺点组合模式的优点是高层模块调用简单,节点可以自由添加。缺点是如果通过组合模式创建过多的对象,可能会对系统造成负担。

总结

本文并没有全部涵盖GoF提出的23种设计模式,而是选择了在前端开发场景下经常用到的几种设计模式进行学习,希望能对前端开发带来帮助。