享元模式是一种结构型设计模式,旨在最大程度地减少系统中对象的数量,通过共享相同状态的对象来减少内存占用和提高性能。在享元模式中,对象分为内部状态和外部状态,内部状态是可以共享的,而外部状态则是每个对象独立拥有的。当我们创建大量相似对象时,通过享元模式,可以有效地优化系统性能,减少内存占用,提高系统的扩展性和灵活性。
在我们的应用程序中,我们希望用户能够添加书籍。所有书籍都有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 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;
}
};
const addBook = (title, author, isbn, availibility, sales) => {
const book = {
...createBook(title, author, isbn),
sales,
availibility,
isbn
};
bookList.push(book);
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);
当你创建大量对象,这可能会耗尽所有可用的RAM时,享元模式是非常有用的。它允许我们最小化消耗的内存量。
在 JavaScript 中,我们可以通过原型继承轻松解决这个问题。如今,硬件具有 GB 的 RAM,这使得享元模式变得没那么重要了。