背景介绍
这是设计模式系列的第十三节,学习的是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到底差在哪
相关活动
本文正在参加「金石计划」