重用现有实例来处理相同的对象
当我们创建大量相似的对象时,享元模式是一种节省内存的有效方法。
在我们的应用中,我们希望用户能够添加书籍。所有的书籍都有,title, author, isbn 。可是,图书馆通常不会只有一本书的副本,一本书通常会有大量的副本。
如果现有的书存在多个副本,那么每次都创建一个书的实例并不是很有用。相反,我们要创建Book构造函数的多个实例来代表一本书。
class Book {
constructor(title, author, isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
}
}
让我们创建一个把新书添加到列表中的功能,如果一本书拥有相同的ISBN号,可以说这是相同的书籍类型。我们不需要创建一本全新的书的实例,反而,我们首先需要检查这本书是否存在
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);
当你要创建大量对象的时候,它可能会耗尽你的RAM内存,使用享元模式能够非常有用的最大限度的减少内存的消耗。
在JavaScript中,我们可以很容易的通过原型继承来解决这个问题。现在的硬件都拥有数GB的RAM内存,这显得享元模式并没那么重要。