设计模式
享元模式
享元模式是一种在创建大量相似对象时节约内存的有效方法。
在我们的应用程序中,我们希望用户能够添加书籍。所有书籍都有一个 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
实例!
1class Book {2 constructor(title, author, isbn) {3 this.title = title;4 this.author = author;5 this.isbn = isbn;6 }7}89const isbnNumbers = new Set();10const bookList = [];1112const addBook = (title, author, isbn, availibility, sales) => {13 const book = {14 ...createBook(title, author, isbn),15 sales,16 availibility,17 isbn18 };1920 bookList.push(book);21 return book;22};2324const createBook = (title, author, isbn) => {25 const book = isbnNumbers.has(isbn);26 if (book) {27 return book;28 } else {29 const book = new Book(title, author, isbn);30 isbnNumbers.add(isbn);31 return book;32 }33};3435addBook("Harry Potter", "JK Rowling", "AB123", false, 100);36addBook("Harry Potter", "JK Rowling", "AB123", true, 50);37addBook("To Kill a Mockingbird", "Harper Lee", "CD345", true, 10);38addBook("To Kill a Mockingbird", "Harper Lee", "CD345", false, 20);39addBook("The Great Gatsby", "F. Scott Fitzgerald", "EF567", false, 20);4041console.log("Total amount of copies: ", bookList.length);42console.log("Total amount of books: ", isbnNumbers.size);
当您创建大量的对象,这些对象可能会消耗掉所有可用的 RAM 时,享元模式很有用。它允许我们最大限度地减少消耗的内存量。
在 JavaScript 中,我们可以通过 原型继承 轻松解决此问题。如今,硬件拥有 GB 级别的 RAM,这使得享元模式变得不那么重要了。