当创建大量相似的对象时,享元模式是一种节省内存的有用方法。
图书馆案例
在应用程序中,我们希望用户能够添加书籍。
所有的书都有书名、作者和书号! 但是,图书馆通常不会只有一本书的副本:它通常有同一本书的多个副本。
如果完全相同的书有多个副本,则每次都创建一个新书实例并不是很有用。
相反,我们想要创建 Book 构造函数的多个实例,代表一本书。
class Book {
constructor(title, author, isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
}
}
让我们创建将新书添加到列表中的功能。
如果一本书具有相同的 ISBN 号,因此是完全相同的书籍类型,我们不想创建一个全新的 Book 实例。
相反,我们应该首先检查这本书是否已经存在。
|
|
如果它还不包含书的 ISBN 号,我们将创建一个新书并将其 ISBN 号添加到 isbnNumbers 集。
|
|
createBook
函数帮助我们创建一种类型书籍的新实例。
但是,图书馆通常包含同一本书的多个副本!
创建一个 addBook
函数,它允许添加同一本书的多个副本。
它应该调用 createBook 函数,该函数返回一个新创建的 Book 实例,或者返回已经存在的实例。
为了跟踪副本总数,让我们创建一个 bookList
数组,其中包含图书馆中的图书总数。
const bookList = [];
const addBook = (title, author, isbn, availibility, sales) => {
const book = {
...createBook(title, author, isbn),
sales,
availibility,
isbn
};
bookList.push(book);
return book;
};
Perfect! 不是每次添加副本时都创建一个新的 Book 实例,可以有效地将已经存在的 Book 实例用于该特定副本。
让我们制作 3 本书的 5 份副本:《哈利波特》、《杀死一只知更鸟》和《了不起的盖茨比》。
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 个 Book 实例!
|
|
优点
当您创建大量对象时,这可能会耗尽所有可用 RAM。
享元模式很有用,它使我们能够最大限度地减少消耗的内存量。
如今,硬件具有 GB 的 RAM,这使得享元模式变得不那么重要。
在 JavaScript 中,我们可以通过原型继承轻松解决这个问题。
知识点
- Set() - Set 对象允许存储任何类型的唯一值,无论是原始值或者是对象引用。