设计模式
在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。 ——维基百科
最近拜读了淘系前端大神修言大佬的《JavaScript 设计模式核⼼原理与应⽤实践》,让我受益匪浅,一直沉浸在业务上重复造轮子的调包虾,每天感觉工作满满,但是未曾感觉自己在进步,此文参照该文章进行了二次消化并记录下来,帮助自己和有同样情况的同学不断加深对设计模式的理解,并运用到日常工作中
#
创建型 - 构造器模式在JavaScript
中,我们使用构造函数去初始化对象,就是应用了构造器模式。
构造器将name、title、role
赋值给对象的过程封装,确保了每个对象都具备这些属性,确保了共性的不变,同时将 name、title、role
各自的取值操作开放,确保了个性的灵活
如果在使用构造器模式的时候,我们本质上是去抽象了每个对象实例的变与不变。那么使用工厂模式时,我们要做的就是去抽象不同构造函数(类)之间的变与不变
#
创建型 - 简单工厂模式产品经理提到不同的英雄类型有不同的特性,比如射手的普攻距离是 500
码,战士是 125
码
#
创建型 - 抽象工厂模式抽象工厂模式的定义,是围绕一个超级工厂创建其他工厂,抽象工厂是佐证“开放封闭原则”的良好素材
#
创建型 - 单例模式单例模式想要做到的是,不管我们尝试去创建多少次,它都只给你返回第一次所创建的那唯一的一个实例。
我的理解单例模式就是共享一块内存,new 一个实例不会再开辟新内存。
面试题:实现一个全局唯一弹窗
#
创建型 - 原型模式原型模式不仅是一种设计模式,它还是一种编程范式(programming paradigm),是 JavaScript 面向对象系统实现的根基。
原型编程范式的核心思想就是利用实例来描述对象,用实例作为定义对象和继承的基础。在 JavaScript 中,原型编程范式的体现就是基于原型链的继承。这其中,对原型、原型链的理解是关键。
ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。类语法不会为 JavaScript 引入新的面向对象的继承模型。 ——MDN
在 JavaScript 中,每个构造函数都拥有一个 prototype 属性,它指向构造函数的原型对象,这个原型对象中有一个 construtor 属性指回构造函数;每个实例都有一个proto属性,当我们使用构造函数去创建实例时,实例的proto属性就会指向构造函数的原型对象。
实现一个深拷贝
#
结构型 - 装饰器模式装饰器模式,又名装饰者模式。它的定义是“在不改变原对象的基础上,通过对其进行包装拓展,使原有对象可以满足用户的更复杂需求”。
在 ES7 中,通过一个@语法糖轻松地给一个类装上装饰器
React 中的装饰器:HOC
高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。
装饰目标组件
#
结构型 - 适配器模式适配器模式通过把一个类的接口变换成客户端所期待的另一种接口,可以帮我们解决不兼容的问题。不影响现有实现方式,兼容调用旧接口的代码
#
结构型 - 代理模式代理模式,式如其名——在某些情况下,出于种种考虑/限制,一个对象不能直接访问另一个对象,需要一个第三者(代理)牵线搭桥从而间接达到访问目的,这样的模式就是代理模式。
最常见的四种代理类型:事件代理、虚拟代理、缓存代理和保护代理
#
事件代理其他三种模式参照修言大佬的掘金小册中有详细介绍。时间代理可能是代理模式最常见的一种应用方式,它的场景是一个父元素下有多个子元素,像这样:
我们现在的需求是,希望鼠标点击每个 a 标签,都可以弹出“我是 xxx”这样的提示。比如点击第一个 a 标签,弹出“我是链接 1 号”这样的提示。这意味着我们至少要安装 6 个监听函数给 6 个不同的的元素(一般我们会用循环,代码如下所示),如果我们的 a 标签进一步增多,那么性能的开销会更大。
#
行为型 - 策略模式定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
终于到了我最喜欢的模式了,这个模式非常实用,在写业务逻辑中经常遇到。同时坚持开放封闭改造,对扩展开放,对修改封闭
修言大神给出的经典案例《询价策略》 需求描述: 当价格类型为“预售价”时,满 100 - 20,不满 100 打 9 折
当价格类型为“大促价”时,满 100 - 30,不满 100 打 8 折
当价格类型为“返场价”时,满 200 - 50,不叠加
当价格类型为“尝鲜价”时,直接打 5 折
他首先将四种价格做了标签化:
使用 if-else ,轻松搞定
缺点: 1.违背了“单一功能”原则。一个 function 里面,它竟然处理了四坨逻辑。 2.违背了“开放封闭”原则。假如增加一个满 100 - 50 的“新人价”怎么办?他只能继续 if-else,由于改动了询价函数,需测试重新回归测试。
解决办法:使用对象映射,同时遵循单一功能和开放封闭原则
假如新增一个条件 新人满 100 返 50
#
行为型 - 状态模式状态模式和策略模式相似,但状态模式强调了类的概念
#
行为型 - 观察者模式观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。
#
行为型 - 发布——订阅模式观察者模式:发布者直接接触订阅者;发布——订阅模式:发布者和订阅者通过中间平台间接接触, 发布者无法感知订阅者
参考文档:掘金小册-《JavaScript 设计模式核⼼原理与应⽤实践》-修言