一、前端设计模式概述
前端设计模式基本情况
设计模式类型
- 创建型:
- 工厂模式(Factory Pattern) :用于创建对象的过程封装在一个工厂类中,将对象的实例化和客户端代码解耦。
- 抽象工厂模式(Abstract Factory Pattern) :提供一个创建相关对象家族的接口,使得一组对象能够协同工作,而无需指定具体类。
- 单例模式(Singleton Pattern) :确保一个类只有一个实例,并提供一个全局访问点来获取该实例。
- 结构型:
- 适配器模式(Adapter Pattern) :将一个类的接口转换成客户端所期望的另一个接口,使得原本不兼容的类能够一起工作。
- 装饰者模式(Decorator Pattern) :在不改变原有对象的情况下,动态地添加功能。
- 代理模式(Proxy Pattern) :为其他对象提供一个代理以控制对这个对象的访问。
- 行为型:
- 观察者模式(Observer Pattern) :定义了对象之间的一对多依赖关系,当一个对象改变状态时,其依赖的对象都会得到通知。
- 策略模式(Strategy Pattern) :定义一系列的算法,将每个算法都封装起来,并使它们可以互换。
- 命令模式(Command Pattern) :将请求封装成对象,从而允许使用不同的请求、队列或者日志来参数化其他对象。
浏览器中的设计模式
- 单例模式
- 定义:单例设计模式旨在确保一个类只有一个实例,并提供全局访问点来获取该实例。即存在全局唯一访问对象。
- 应用场景:
- 全局状态管理:浏览器中可能存在一些需要在整个应用中共享的状态,例如用户登录信息、应用配置等。使用单例模式可以确保这些状态只有一个实例,避免了多个实例之间的不一致性。
- 资源池管理:有时候需要管理一些昂贵的资源,如数据库连接、网络请求池等。通过使用单例模式,可以保证只有一个实例,避免过多地消耗系统资源。
- 全局事件管理:浏览器应用可能需要在不同的组件之间传递事件,而一个全局的事件管理器可以通过单例模式来实现,确保事件的一致性和可控性。
- 缓存管理:浏览器中经常需要使用缓存来提高性能。一个单例的缓存管理器可以协调缓存的读取、写入和过期策略,避免重复的缓存实例。
- 发布订阅模式
- 定义:发布订阅模式允许对象(观察者)订阅另一个对象(主题或发布者)的事件,以便在事件发生时接收通知和执行相应的操作。即一种订阅机制,可在被订阅对象发生变化时通知订阅者。
- 应用场景:
- 事件处理:在浏览器中,页面的交互和动态性往往通过事件来实现。发布-订阅模式可以帮助管理各种事件的订阅和处理。
- 组件通信:在复杂的前端应用中,不同的组件可能需要相互通信,例如一个组件的状态变化需要更新另一个组件。发布-订阅模式可以实现解耦和跨组件通信。
- 异步操作完成通知:当异步操作完成时,例如网络请求返回数据,可以使用发布-订阅模式通知其他部分进行后续处理。
二、JavaScript 和前端框架中的设计模式
JavaScript 中的设计模式
1. 原型模式
- 定义:原型模式(Prototype Pattern)是一种创建对象的设计模式,它通过复用现有对象的属性和方法来创建新的对象,从而提高代码的可维护性和可复用性。即复制已有对象来创建新的对象。
- 应用场景:
- 对象实例化开销大:如果创建一个对象的过程开销较大,包括初始化复杂的属性和方法,使用原型模式可以在一开始创建原型对象,然后通过克隆来创建新对象,从而节省创建时间和资源。
- 共享相似属性和方法:当多个对象具有相似的属性和方法时,可以将这些共享的部分放在原型对象上,避免重复定义和占用额外的内存。
- 继承:原型链机制是 JavaScript 中实现继承的基础。通过原型链,子类对象可以继承父类对象的属性和方法,实现了对象之间的继承关系。
- 框架和库开发:在开发框架或库时,原型模式可以用来创建共享的工具函数、插件和模块,从而提供一致性的接口和功能。
- 缓存和资源池:原型模式可以用于创建缓存池或资源池,其中对象是已经初始化并准备好使用的。当需要使用时,可以从池中克隆对象,避免重复创建和销毁对象的开销。
- 事件管理:在事件驱动的应用中,原型模式可以用来实现事件管理器,让多个对象能够订阅和触发事件,实现松耦合的通信。
- 数据共享:在数据处理场景中,如果多个对象需要访问同一份数据,可以使用原型模式创建一个数据对象,然后让其他对象通过克隆获取数据的副本,保持数据一致性。
- 前端框架组件:许多前端框架(例如 Vue、React)中使用了原型模式来创建组件,实现组件的复用和状态管理。
2. 代理模式
- 定义:代理模式(Proxy Pattern)是一种结构型设计模式,它允许一个对象(代理对象)充当另一个对象(真实对象)的接口,以控制对真实对象的访问。可自定义控制对原对象的访问方式,并且允许在更新前后做一些额外处理。
- 应用场景:
- 远程代理:当对象位于不同的地址空间时,可以使用代理模式实现远程代理,允许在本地访问远程对象的方法。
- 虚拟代理:当一个对象的创建和初始化开销很大时,可以使用代理模式实现虚拟代理,延迟真正对象的创建和初始化,只有在需要时才进行。
- 保护代理:在访问对象时进行权限验证,只有当权限通过时才允许访问真实对象,这在安全性要求较高的系统中很有用。
- 缓存代理:代理对象可以缓存真实对象的结果,在后续相同请求时直接返回缓存的结果,提高访问速度。
- 动态代理:代理对象在运行时动态生成,根据需要添加额外的操作,如记录日志、性能监测等。
3. 迭代器模式
- 定义:迭代器模式(Iterator Pattern)是一种行为型设计模式,用于提供一种方法来访问聚合对象(如数组、列表、集合等)的元素,而无需暴露其内部结构。即可以在不暴露数据类型的情况下访问集合中的数据。
- 应用场景:数据结构中有多种数据类型,列表,树等,提供通用操作接口。
- 遍历集合:迭代器模式可以帮助我们更简单地遍历数组、列表、集合等聚合对象,无需直接操作索引或循环。
- 解耦聚合和遍历:迭代器将遍历逻辑从聚合对象中抽离出来,使得聚合对象和遍历逻辑可以独立变化,增加了代码的灵活性。
- 提供统一遍历接口:通过迭代器模式,我们可以为不同类型的聚合对象提供统一的遍历接口,简化代码的编写。
- 隐藏聚合内部结构:迭代器模式允许我们遍历聚合对象的元素,而无需了解其内部的存储结构。
- 延迟加载:迭代器可以实现延迟加载,即只有在需要时才真正获取元素,避免一次性加载大量数据。
前端框架中的设计模式
1. 代理模式
- 定义:在前端框架中,代理模式是一个常见的设计模式,用于控制和管理组件之间的通信、数据流和事件传递。
- 应用场景:DOM、前端组件、文件目录、部门目录。
- 事件代理: 前端框架中的事件代理是一种常见的应用。事件代理通过在父级元素上监听事件,然后根据事件的目标元素来触发相应的处理函数。这样可以减少事件处理程序的数量,提高性能,并且可以应对动态添加和删除元素的情况。
- 数据代理: 前端框架中的状态管理常常采用代理模式。通过引入数据代理,组件可以访问中心化的状态存储,而不必直接操作状态。数据代理可以控制状态的访问权限、实现数据响应式,以及在状态变化时通知相关组件进行更新。
- 虚拟 DOM 代理: 前端框架中的虚拟 DOM 是为了减少 DOM 操作的开销而设计的。虚拟 DOM 代理可以作为真实 DOM 的一个轻量级代理,负责处理虚拟 DOM 对象的创建、比对和更新操作,从而减少直接对真实 DOM 的操作,提高性能。
- 路由代理: 前端框架的路由功能也常常采用代理模式。路由代理可以负责监听 URL 变化,根据不同的路由规则调用相应的组件,并实现路由状态管理,从而实现单页应用的页面切换和导航。
- 组件通信代理: 前端框架中的组件之间需要进行通信,而代理模式可以用于实现组件通信。通过代理,可以将组件之间的通信抽象为消息、事件或者状态变更,实现组件之间的解耦,提高可维护性。
- 懒加载代理: 前端框架中的懒加载功能常常采用代理模式。通过代理组件,在需要的时候再加载相关的代码和资源,避免一次性加载过多内容,提高初始加载速度。
2. 组合模式
- 定义:在前端框架中,组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树状结构,以表示部分-整体的层次关系。可多个对象组合使用,成为一个单个对象,也可单个对象独立使用。
- 应用场景:DOM、前端组件、文件目录、部门目录。
- UI 组件库: 前端框架中的 UI 组件库常常使用组合模式。例如,一个界面可以由多个不同类型的组件组成,这些组件可以是按钮、输入框、面板等,通过组合模式可以将它们组织成一个整体界面。
- 菜单导航: 前端应用的导航菜单通常是一个树形结构,其中每个菜单项可以有子菜单项。组合模式可以用于构建这种层次结构,使得导航菜单可以统一地处理不同层级的菜单项。
- 文件系统: 在文件系统中,目录和文件可以看作是一个树形结构,其中目录可以包含子目录和文件。组合模式可以用于表示文件系统的层次结构,使得可以以一致的方式操作文件和目录。
- 组织结构: 在展示组织结构、团队层级等信息时,组合模式可以帮助我们构建层次关系,使得可以以统一的方式展示不同层级的信息。
- 嵌套表单: 前端应用中的嵌套表单可以使用组合模式,将表单字段组织成层次结构,使得可以一致地处理单个字段和组合字段。
本篇笔记为个人总结,学习交流使用,欢迎各位大佬评价指正,非常感谢!