跳至主要內容
基本原则

二十三个经典的 设计模式 已经过完了 ,这里再把一些基本原则过一下,以便平时开发中可以更好的体会。

单一职责原则 SRP(Single Responsibility Principle)

There should never be more than one reason for a class to change." In other words, every class should have only one responsibility.


h7ml设计模式frontend设计模式frontend大约 6 分钟
桥接模式

组合模式要是用在复杂类的抽离、运行时切换不同方法等,比较难理解,这里 讲的不错。

目前开发中也没有遇到过,此处留坑。


h7ml设计模式frontend设计模式frontend小于 1 分钟
状态模式

状态模式主要应用在游戏、工作流引擎中,其实就是有限状态机的实现,目前开发中还没有遇到过,此处留坑。

但状态模式也比较有意思,它可以将过多的 if...else... 或者 switch...case... 抽离出来,使得代码的扩展性更好一些。

举个例子,详细解释可以查看极客时间的 设计模式之美 讲的。

一个超级马里奥的例子,吃了蘑菇、吃了花都会有不同的状态进行转移。


h7ml设计模式frontend设计模式frontend大约 2 分钟
命令模式

命令模式主要应用在需要延迟执行请求、支持撤回的场景中,可能在文本编辑器中有应用,我目前没有使用过,这里就留坑了。

命令模式本质上就是将数据和操作封装为一个对象,实现操作的撤回、延迟等。

这里贴一下 Youtube 一个博主举的 计算器例子


h7ml设计模式frontend设计模式frontend大约 2 分钟
组合模式

组合模式主要应用在符合树状结构的场景中,父节点和子节点实现统一接口,父节点委托给子节点进行执行。

其中父节点就可以当作组合对象,用户调用的时候无需关系是组合对象还是子对象,面向接口调用即可。

目前开发中还没有遇到过,此处留坑。


h7ml设计模式frontend设计模式frontend小于 1 分钟
工厂模式

工厂模式是如果业务场景中需要创建多个类似的对象,然后充斥了大量的 if...else... ,此时可以将创建对象的部分抽离出来。

简单工厂模式就是直接抽离,什么都不改,只是将 if..else... 进行了转移。

工厂模式是每一个对象都创建一个工厂类,业务中先得到一个工厂,然后通过工厂得到对象。

抽象工厂模式是每一个工厂类可以生成多种对象。

GoF 中只有工厂模式和抽象工厂模式。

目前开发中还没有遇到过,此处留坑。


h7ml设计模式frontend设计模式frontend小于 1 分钟
中介者模式

中介者模式用于解决多个对象之间交互过于复杂的问题,从多对多的关系转为一对多的关系。

img
img

观察者 模式有些像,区别在于观察模式中的 EventBus 不处理业务逻辑,只是单纯的转发消息。


h7ml设计模式frontend设计模式frontend小于 1 分钟
解释器模式

解释器模式应用在对自定义语法的解释上,自己规定一些新语法,然后通过解释器模式,语法的每种表达式进行细分,最终解释整个表达式。

可能会用在编译器、规则引擎上。

目前自己还没有遇到过,此处留坑。


h7ml设计模式frontend设计模式frontend小于 1 分钟
备忘录模式

备忘录模式主要是用于来防丢失、撤销、恢复等场景,定义是:在不违背封装原则的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便之后恢复对象为先前的状态。

需要三个类, Memento 类提供保存对象和得到对象的方法, Originator 类利用 Memento 类提供保存和读取自身状态的方法,Caretaker 类来记录所有的备份。

维基百科 的例子贴过来。


h7ml设计模式frontend设计模式frontend大约 1 分钟
访问者模式

访问者模式主要作用是实现数据和操作的分离,可以在不改变数据类的同时,增加新的操作类型。

其主要通过「双分派」的思想实现。给原数据类传入一个 Visitor 方法,原数据类调用 Visitor 提供的方法,并将自己通过 this 传给 VisitorVistior 实现相关操作。

目前开发中还没有遇到过,此处留坑。


h7ml设计模式frontend设计模式frontend小于 1 分钟
原型模式

原型模式在基于类的语言中作用大一些,当构造函数比较复杂,有一些耗时操作,此时通过 new 去创建对象不划算,可以通过 clone 的方法,直接基于已有对象 copy 一个。

js 属于基于原型的面向对象的编程语言,本身就是基于一个对象来生成另一个对象,并没有真正的类。

我们可以直接通过 Object.create 或者 json 序列化反序列化 copy 一个对象。


h7ml设计模式frontend设计模式frontend小于 1 分钟
享元模式

享元模式主要用于性能优化,当出现大量的重复对象时,为了防止内存被撑爆,可以抽离一些公共部分进行共享。

目前开发中还没有遇到过,此处留坑。


h7ml设计模式frontend设计模式frontend小于 1 分钟
迭代器模式

场景

for...of.... 的原理是?

迭代器模式

看下 维基百科 给的定义:

In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.


h7ml设计模式frontend设计模式frontend大约 3 分钟
建造者模式

场景

如果我们定义了某个函数:

function getPhone(size, type, screen, price=100) {
  ...
}

h7ml设计模式frontend设计模式frontend大约 5 分钟
外观模式

场景

网络请求中,我们一般使用 axios 库,支持用 Promise 风格调用。

axios
  .get('/api/user', {
    params: {
      ID: '123',
    },
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

axios
  .post(
    '/api/user',
    {
      firstName: 'wind',
      lastName: 'liang',
    },
    {
      headers: { 'Content-Type': 'application/json' },
    }
  )
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

h7ml设计模式frontend设计模式frontend大约 3 分钟
适配器模式

场景

当我们使用第三方库的时候,常常会遇到当前接口和第三方接口不匹配的情况,比如使用一个 Table 的组件,它要求我们返回的表格数据格式如下:

{
  code: 0, // 业务 code
  msg: '', // 出错时候的提示
  data: {
     total: , // 总数量
     list: [], // 表格列表
  }
};

h7ml设计模式frontend设计模式frontend大约 5 分钟
模版模式

场景

示例代码来源于极客时间课程,React Hooks 核心原理与实战,顺便推荐一下,很不错的课程

平常开发中一定遇到过这样的场景:发起异步请求,loading 状态显示,获取数据并显示在界面上,如果遇到错误还会显示错误状态的相关展示。

为了方便运行,先写一个 mock 数据的方法:

const list = {
  page: 1,
  per_page: 6,
  total: 12,
  total_pages: 2,
  data: [
    {
      id: 1,
      email: 'george.bluth@reqres.in',
      first_name: 'windliang',
      last_name: 'windliang',
      avatar: 'https://reqres.in/img/faces/1-image.jpg',
    },
    {
      id: 2,
      email: 'janet.weaver@reqres.in',
      first_name: 'Janet',
      last_name: 'Weaver',
      avatar: 'https://reqres.in/img/faces/2-image.jpg',
    },
    {
      id: 3,
      email: 'emma.wong@reqres.in',
      first_name: 'Emma',
      last_name: 'Wong',
      avatar: 'https://reqres.in/img/faces/3-image.jpg',
    },
  ],
};
export const getDataMock = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(list);
    }, 2000);
  });

h7ml设计模式frontend设计模式frontend大约 7 分钟
单例模式

场景

如果需要实现一个全局的 loading 遮罩层,正常展示是这样的:

image-20220206173318902
image-20220206173318902

h7ml设计模式frontend设计模式frontend大约 7 分钟
责任链模式

场景

leetcode 65 题 判断是否是合法的数字:

image-20220204102426236
image-20220204102426236

h7ml设计模式frontend设计模式frontend大约 6 分钟
发布订阅模式

建议先看一下上篇 观察者模式 ,发布订阅模式和观察者模式本质上还是一样的,并且发布订阅模式也没有在经典的设计模式书 GoF 中出现,很多地方也直接把两者看成一种设计模式了。

GoF 的名字也有个有趣的故事,这里 贴过来:


h7ml设计模式frontend设计模式frontend大约 6 分钟
2