设计模式 - 享元模式

文章介绍了享元模式在JavaScript中的应用,如何通过共享相同状态的书籍对象减少内存消耗,提高性能。通过创建Book类和addBook函数实现对重复书籍副本的高效管理,即使在大数量书籍场景下也保持系统性能和扩展性。
摘要由CSDN通过智能技术生成

享元模式是一种结构型设计模式,旨在最大程度地减少系统中对象的数量,通过共享相同状态的对象来减少内存占用和提高性能。在享元模式中,对象分为内部状态和外部状态,内部状态是可以共享的,而外部状态则是每个对象独立拥有的。当我们创建大量相似对象时,通过享元模式,可以有效地优化系统性能,减少内存占用,提高系统的扩展性和灵活性。

在我们的应用程序中,我们希望用户能够添加书籍。所有书籍都有titleauthor和 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,这使得享元模式变得没那么重要了。

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值