js享元模式设计原理以及应用案例

享元模式是一种用于性能优化的设计模式,尤其在前端编程中,它通过对象复用减少内存消耗。本文详细介绍了享元模式的内部状态与外部状态、享元对象、享元工厂以及客户端的角色,并通过实例展示了如何使用享元模式优化大量书籍数据的渲染,从而提高性能。同时,也讨论了享元模式的优缺点。
摘要由CSDN通过智能技术生成
摘要

享元模式是用于性能优化的设计模式之一,在前端编程中有重要的应用,尤其是在大量渲染DOM的时候,使用享元模式及对象池技术能获得极大优化。本文介绍了享元模式的概念,并将其用于渲染大量列表数据的优化上。

初识享元模式
在面向对象编程中,有时会重复创建大量相似的对象,当这些对象不能被垃圾回收的时候(比如被闭包在一个回调函数中)就会造成内存的高消耗,在循环体里创建对象时尤其会出现这种情况。享元模式提出了一种对象复用的技术,即我们不需要创建那么多对象,只需要创建若干个能够被复用的对象(享元对象),然后在实际使用中给享元对象注入差异,从而使对象有不同的表现。
为了要创建享元对象,首先要把对象的数据划分为内部状态和外部状态,具体何为内部状态,何为外部状态取决于你想要创建什么样的享元对象。
举个例子:
书这个类,我想创建的享元对象是“技术类书籍”,让所有技术类的书都共享这个对象,那么书的类别就是内部状态;而书的书名,作者可能是每本书都不一样的,那么书的书名和作者就是外部状态。或者换一种方式,我想创建“村上春树写的书”这种享元对象,然后让所有村上春树写的书都共享这个享元对象,此时书的作者就为内部状态。当然也可以让作者、分类同时为内部状态创建一个享元对象。
享元对象可以按照内部状态的不同创建若干个,比如技术类书,文学类书,鸡汤类书三个。在实践的时候会发现,抽象程度越高,所创建的享元对象就越少,但是外部状态就越多;相反抽象程度越低,所需创建的享元对象就越多,外部状态就越少。特别地,当对象的所有状态都归为内部状态时,此时每个对象都可以看作一个享元对象,但是没有被共享,相当于没用享元模式。

一.享元模式的结构
1.内部状态与外部状态

在享元对象内部并且不会随着环境改变而改变的共享部分,可以称之为享元对象的内部状态,反之随着环境改变而改变的,不可共享的状态称之为外部状态。

简单地说,内部状态是对象本身的属性,外部状态是管理这些对象所需的额外的属性,相同的对象内部状态相同,但外部状态可能不同(比如2本相同的书被2个人借走了)

2.享元

享元是相似对象(书的例子中指的是完全相同的书,而不是题材相似的书)间可共享的属性的集合,比如书的名字、作者、ISBN等等,完全相同的书这些信息都是相同的,没有必要把相同的属性在多个相似对象中保存多份,享元负责把这些属性分离出来,以便共享

如果可共享的属性比较复杂,还可以增加抽象享元,以及与之对应的具体享元,还可以有复合享元

3.享元工厂

享元工厂负责创建并管理享元,实现共享逻辑(创建时判断是否存在,已存在就返回现有对象,否则创建一个)

4.客户端(Client)

Client负责调用享元工厂,并存储管理相似对象所需的额外属性(比如书的id,借/还日期,是否在馆等等)
实例:
如果需要管理的书籍数量非常大,那么使用享元模式节省的内存将是一个可观的数目

// 图书管理
  // 书的属性:id,title,author,genre,page count,publisher id,isbn
  // 管理所需的额外属性:checkout date,checkout member,due return date,availability
    // 享元(存储内部状态)
    function Book(title, author, genre, pageCount, publisherId, isbn) {
   
      this.title = title;
      this.author = author;
      this.genre = genre;
      this.pageCount = pageCount;
      this.publisherId = publisherId;
      this.isbn = isbn;
    }

    // 享元工厂(创建/管理享元)
    var BookFactory = (function () {
   
      var existingBooks = {
   };
      var existingBook = null;
      return {
   
        createBook: function (title, author, genre, pageCount, publisherId, isbn) {
   
          // 如果书籍已经创建,,则找到并返回
          // !!强制返回bool类型
          existingBook = existingBooks[isbn];
          if (!!existingBook) {
   
            return existingBook;
          } else {
   
            // 如果不存在选择创建该书的新实例并保存
            var book = new Book(title, author, genre, pageCount, publisherId, isbn);
            console.log(book);
            existingBooks[isbn] = book;
            return book;
          }
        }
      }
    })();

    // 客户端(存储外部状态)
    var BookRecordManager = (function () {
   
      var bookRecordDatabase = {
   };
      return {
   
        // 添加新书到数据库
        addBookRecord: function (id, title, author, genre, pageCount, publisherId, isbn,
          checkoutDate, checkoutMember, dueReturnDate, availability) {
   
          var book = BookFactory.createBook(title, author, genre, pageCount, publisherId, isbn);
          bookRecordDatabase[id] = {
   
            checkoutMember: checkoutMember,
            checkoutDate: checkoutDate,
            dueReturnDate: dueReturnDate,
            availability: availability,
            book: book
          }
        },
        updateCheckStatus: function (bookId, newStatus, checkoutDate
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值