什么?没听说过享元模式,快来学学

823 阅读3分钟

背景介绍

这是设计模式系列的第十三节,学习的是patterns.dev里设计模式中享元模式内容,由于是资料是英文版,所以我的学习笔记就带有翻译的性质,但并不是翻译,记录的是自己的学习过程和理解

关于设计模式前十二节的内容,在文末会有直达链接。

极简释义

在处理同一对象的不同状态时,复用已有实例对象。

写在前面

享元模式在使用大量同一对象时,是一种很有效的节约内存提升性能的方式。

比如说,在一个应用程序中,用户可以添加书籍,所有书籍都有标题,作者,和统一的书号;然而一本往往有多个副本

针对每个副本创建一个新的书籍实例,这是一个有效的做法,而复用已有的示例对象是很有用的。我们可以通过Book的构造方法创建多个实例对象:

class Book {
  constructor(title, author, isbn) {
    this.title = title;
    this.author = author;
    this.isbn = isbn;
  }
}

下面我们来新增一个功能:把新书添加到列表,如果书号已经存在Map之中,我们就没必要创建新的示例对象,直接复用已有实例对象:

const books = new Map();

const createBook = (title, author, isbn) => {
  const existingBook = books.has(isbn);
 
  if (existingBook) {
    return books.get(isbn);
  }
 
  const book = new Book(title, author, isbn);
  books.set(isbn, book);
 
  return book;
};

当然,如果书号不存在,我们就创建书籍对象添加到以书号isBn为键的Map集合里。

一般会有多个读者同一本书,这样就需要记录同一本书的多个副本,这时就可以把这些副本添加到一个数组中,方便统一管理。

const bookList = [];
 
const addBook = (title, author, isbn, availability, sales) => {
  const book = {
    ...createBook(title, author, isbn),
    sales,
    availability,
    isbn,
  };
 
  bookList.push(book);
  return book;
};

这样每次新增一个读者,添加一个副本时就不会盲目地新增一本书了,从而最大限度复用已存在的book实例对象;

接下来,我们来创建5个副本,总共涉及到了3本书:

addBook("Harry Potter", "JK Rowling", "AB123", false, 100);
addBook("Harry Potter", "JK Rowling", "AB123", true, 50);
addBook("To Kill a Mockingbird", "Harper Lee", "CD345", true, 10);
addBook("To Kill a Mockingbird", "Harper Lee", "CD345", false, 20);
addBook("The Great Gatsby", "F. Scott Fitzgerald", "EF567", false, 20);

现在内存中,也只有5个副本和3本书,而不是5本书,在线示例

总结

享元模式在我们需要创建大量实例对象时,是很有效的,可以最大限度地减少内存占用。

当然在JavaScript中,我们可以通过原型继承来轻松解决这个问题。在内存以GB为单位的今天,享元模式正变得那么重要了。

相关推荐

第一节:单例模式:高并发造成的数据统计困难?看我单例模式一招制敌

第二节:替身模式:JS和迪丽热巴一样有专业替身?没听过的快来补补课...

第三节:供应商模式:还在层层传递props?来学学非常实用的供应商模式吧

第四节:原型模式:都知道JavaScript原型,但设计模式里的原型模式你会用吗?

第五节:视图和逻辑分离模式:React Hooks时代,怎么实现视图与逻辑分离呢?

第六节:观察者模式:是时候拿出高级的技术了————观察者模式

第七节:模块化模式:前端性能优化进阶篇——动态加载模块基础补遗

第八节:混合模式:在React Hook时代,Object.assign这种混合写法还要用吗?

第九节:中间件模式:如何使用中间件优化多对多通信?

第十节:高阶组件模式:在React Hooks时代,高阶组件只能感叹:既生瑜何生亮?

第十一节:传递render方法模式:如何在提升state的层级时,避免父级子组件重新渲染问题

第十二节:React Hooks:和React Hook相比class Component到底差在哪 

相关活动

本文正在参加「金石计划」