本文将深入探讨 Flyweight 模式,并以 JavaScript 代码为例,阐述其在实际应用中的优势。
模式概述
Flyweight 模式是一种旨在减少内存消耗的软件设计模式。它通过共享相同状态的对象来减少对象数量,从而降低内存占用。
场景分析
假设我们要构建一个图书馆管理系统,其中需要存储大量书籍信息。每本书都包含书名、作者和 ISBN 号,而同一本书可能存在多个副本。如果我们为每个副本都创建一个新的 Book 对象,那么当副本数量众多时,内存占用将会非常大。
Flyweight 模式解决方案
为了解决这个问题,我们可以使用 Flyweight 模式。该模式的核心思想是:
- 共享状态: 将所有书籍的共同属性(如书名、作者、ISBN 号)存储在一个共享的
Book对象中。 - 外部状态: 将每个副本的独有属性(如副本数量、可用性等)存储在外部对象中。
代码示例
以下代码展示了如何使用 Flyweight 模式来存储书籍信息:
class Book {
constructor(title, author, isbn) {
this.title = title;
this.author = author;
this.isbn = isbn;
}
}
const books = new Map(); // 存储所有书籍
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;
};
const bookList = []; // 存储所有副本
const addBook = (title, author, isbn, availability, sales) => {
const book = {
...createBook(title, author, isbn),
sales,
availability,
isbn,
};
bookList.push(book);
return book;
};
// 添加 5 个副本,包含 3 本不同的书籍
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); // 5
console.log("Total amount of books: ", books.size); // 3
在上面的代码中,createBook 函数用于创建或获取 Book 对象。如果 isbn 已经存在,则直接返回已存在的 Book 对象,否则创建一个新的 Book 对象并将其存储在 books Map 中。addBook 函数则用于添加副本,它会调用 createBook 函数获取 Book 对象,并将副本信息存储在 bookList 数组中。
总结
Flyweight 模式通过共享状态来减少对象数量,从而有效降低内存占用。在实际应用中,当需要创建大量相似对象时,Flyweight 模式可以显著提高应用程序的性能。
参考文献
- Flyweight - Refactoring Guru
- Flyweight Design Pattern - How To Do In Java
注意: 随着硬件性能的提升,Flyweight 模式在实际应用中的重要性有所下降。但是,在需要处理大量数据时,它仍然是一种有效的优化策略。
参考资料:
Flyweight Pattern