当我们创建大量相似的对象时,享元模式是节省内存的一种有用方法。
在我们的应用程序中,我们希望用户能够添加书籍。所有书籍都有一个title、一个author和一个isbn编号!然而,图书馆通常不仅仅拥有一本书的一本:它通常拥有同一本书的多本。
如果同一本书有多个副本,那么每次创建一个新的书籍实例并不是很有用。相反,我们想要创建Book代表一本书的构造函数的多个实例。
class Book {
constructor(title, author, isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
}
}
让我们创建将新书添加到列表中的功能。如果一本书具有相同的 ISBN 编号,因此是完全相同的书籍类型,我们不想创建一个全新的Book实例。相反,我们应该首先检查这本书是否已经存在。
const books = new Map();
const createBook = (title, author, isbn) => {
const existingBook = books.has(isbn);
if (existingBook) {
return books.get(isbn);
}
};
如果它还不包含图书的 ISBN 编号,我们将创建一本新图书并将其 ISBN 编号添加到集合中isbnNumbers。
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;
};
该createBook函数帮助我们创建一种类型的书籍的新实例。然而,图书馆通常包含同一本书的多本!让我们创建一个addBook函数,它允许我们添加同一本书的多个副本。它应该调用该createBook函数,该函数返回新创建的Book实例,或返回已经存在的实例。
为了跟踪总册数,让我们创建一个bookList包含图书馆中图书总数的数组。
const bookList = [];
const addBook = (title, author, isbn, availability, sales) => {
const book = {
...createBook(title, author, isbn),
sales,
availability,
isbn,
};
bookList.push(book);
return book;
};
完美的!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实例!
class Book {
constructor(title, author, isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
}
}
const isbnNumbers = new Set();
const bookList = [];
const addBook = (title, author, isbn, availibility, sales) => {
const book = {
...createBook(title, author, isbn),
sales,
availibility,
isbn
};
bookList.push(book);
return book;
};
const createBook = (title, author, isbn) => {
const book = isbnNumbers.has(isbn);
if (book) {
return book;
} else {
const book = new Book(title, author, isbn);
isbnNumbers.add(isbn);
return book;
}
};
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);
console.log("Total amount of copies: ", bookList.length);
console.log("Total amount of books: ", isbnNumbers.size);
Open CodeSandbox
当您创建大量对象时,享元模式非常有用,这可能会耗尽所有可用 RAM。它允许我们最大限度地减少消耗的内存量。
在JavaScript中,我们可以通过原型继承轻松解决这个问题。如今,硬件拥有 GB 的 RAM,这使得享元模式不再那么重要。