Appearance
享元模式
在创建大量的相似对象时,享元模式是一个有效的节省内存的方式。
在我们的应用中,我们想要用户可以添加书籍。每一本书都有 title
、author
、isbn
属性。然而通常在一个图书馆中,同一本书不会只有一份,而是有多份副本。
如果同一本书有多份副本,那么每次都创建新的书籍实例就没什么用了。相反,我们希望创建 Book
构造函数的多个实例,它们代表一本书。
js
class Book {
constructor(title, author, isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
}
}
我们来创建一个将新书添加到列表中的功能。如果两本书有相同的 ISBN 号,那么它们是完全相同的书籍类型,这时我们将不会创建一个全新的 Book 实例。所以我们应该首先检查这本书是否已经存在。
js
const books = new Map();
const createBook = (title, author, isbn) => {
const existingBook = books.has(isbn);
if (existingBook) {
return books.get(isbn);
}
};
如果当前 ISBN 不存在,我们将会创建一本新的书,并且将当前 ISBN 号放进 isbnNumbers
集合中。
js
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;
};
The createBook
function helps us create new instances of one type of book. However, a library usually contains multiple copies of the same book! Let’s create an addBook
function, which allows us to add multiple copies of the same book. It should invoke the createBook
function, which returns either a newly created Book
instance, or returns the already existing instance.
In order to keep track of the total amount of copies, let’s create a bookList
array that contains the total amount of books in the library.
js
const bookList = [];
const addBook = (title, author, isbn, availability, sales) => {
const book = {
...createBook(title, author, isbn),
sales,
availability,
isbn,
};
bookList.push(book);
return book;
};
Perfect! Instead of creating a new Book
instance each time we add a copy, we can effectively use the already existing Book
instance for that particular copy. Let’s create 5 copies of 3 books: Harry Potter, To Kill a Mockingbird, and The Great Gatsby.
js
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);
Although there are 5 copies, we only have 3 Book
instances!
The flyweight pattern is useful when you’re creating a huge number of objects, which could potentially drain all available RAM. It allows us to minimize the amount of consumed memory.
In JavaScript, we can easily solve this problem through prototypal inheritance. Nowadays, hardware has GBs of RAM, which makes the flyweight pattern less important.
References
Flyweight - Refactoring Guru
Flyweight Design Pattern - How To Do In Java