你不知道的javascript设计模式(十二) ----享元模式

简介: 你不知道的javascript设计模式(十二) ----享元模式

前言

       同学们,上一章我们介绍了模板方法模式,这是一种基于继承的设计模式,通过设计抽象类可以避免类似类的重复定义,并且因为js的特殊原型克隆,我们也就js的实现方式进一步说明了模板方法模式,今天我们将进一步介绍一种新的设计模式,享元模式。


正文

享元模式的定义

       享元模式是一种用于性能优化的模式,享元模式的核心是利用共享技术来有效支持大量细粒度的对象。尤其是对于javascript,浏览器所能分配的内存并不多,所以怎样节省内存就显得很有意义

       举一个例子方便大家理解,假设有个衣服工厂,有50套男士衣服和50套女士衣服,这时候工厂需要生产塑料模特来穿这些衣服用于宣传,如果用程序来实现,不用享元模式的情况下,我们可能就会创建100个对象来穿这些衣服,但是随着衣服的增多,创建的对象也会越来越多,导致最后消耗的资源难以承受

       换个思路想一想,如果我们不创建100个对象呢,反正男士的衣服可以用一套男士模特来试穿,而女士只需要一套女士模特来试穿,我们是不是只需要创建两个对象就行呢

       这就是最简单的一个享元模式的思想,通过抽取共同点,并且用不同点来区分,尽量减少创建消耗的资源,达到一个公用的目的


内部状态与外部状态

       享元模式要求将对象的属性划分为内部状态和外部状态,上一节我们说到享元模式的目标就是为了尽量减少共享对象的数量,关于怎么区分内部状态和外部状态,遵循以下原则:

  • 内部状态存储于对象内部
  • 内部状态可以被一些对象共享
  • 内部状态独立于具体的场景,通常不会改变
  • 外部状态取决于具体的场景,并根据场景而变化,外部状态不能被共享

       在上面的例子中,性别就是内部对象,因为我们根据性别来区别出了两种模特,而衣服类型就是外部状态,因为可以有各种各样的衣服可以选择。所以,通常来说,内部对象有多少种组合,享元模式就需要至少创建多少对象


享元模式的实现

       还是之前的例子,我们先来看看享元模式直接实现这个衣服工厂应该怎么实现

640.png

       这样为这100件衣服我们就创建出了100个对象,如果衣服再多一点比如1000件,谷歌火狐这些浏览器还可以勉强支持,ie浏览器直接就当场去世了,然后我们换成之前说的享元模式的方法来实现,sex作为内部属性,underwear作为外部属性

640.png

       这样,我们通过享元模式只需要创建2个对象就可以实现与第一种方法相同的效果了

对象池

       提了享元模式,就不得不谈一下对象池的内容了,什么是对象池呢,假设一个图书馆,里面现在有三本红宝书,有读者来借书的时候,如果还有,直接借给读者就是,如果这时候有四名读者来借红宝书,三本就不够用了,图书馆不得不去再买一本来借给第四名读者。有则取,无则造,这就是对象池。根据上面的思路我们不难实现一个通用的对象池

640.png

       利用这个对象池我们可以很轻松地创建一个Model类型的对象池,来保证只要塑料模特够用,咱就不创建新的

       有了这个对象池,上面的案例我们就可以这么实现

640.png

       这样做的好处就是,从头到尾,其实就创建了一个模特对象而已,后面的create一直在复用之前的对象


对象池与享元模式的区别

       对象池与享元模式有很大的相似处,都是复用对象,但是其实两者是有本质上的区别的。

  • 池化技术中的“复用”可以理解为“重复使用”,主要目的是节省时间(比如从对象池中取一个对象,不需要重新创建)。在任意时刻,每一个对象、连接、线程,并不会被多处使用,而是被一个使用者独占,当使用完成之后,放回到池中,再由其他使用者重复利用。
  • 享元模式中的“复用”可以理解为“共享使用”,在整个生命周期中,都是被所有使用者共享的,主要目的是节省空间。

       我们可以很明显发现,在上面对象池的例子中,并没有分离内部状态和外部状态的过程,所以对象池与享元模式是完全不可同日而语的。

小结

       这一章我们介绍了享元模式,当在业务逻辑中需要创建大量对象的时候,我们就可以考虑利用享元模式,分离这些对象的内部和外部状态,实现对象间的复用,从而减少重复资源上的消耗,我们还介绍了对象池,对象池与享元模式有相似之处,同样是为了实现对象的复用,但是与享元模式不同,在复用对象被使用的时候,是处于被独占的状态,且也没有对内部和外部状态的区分,要着重注意两者的不同

目录
相关文章
|
7天前
|
设计模式 存储 缓存
「全网最细 + 实战源码案例」设计模式——享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在减少大量相似对象的内存消耗。通过分离对象的内部状态(可共享、不变)和外部状态(依赖环境、变化),它有效减少了内存使用。适用于存在大量相似对象且需节省内存的场景。模式优点包括节省内存和提高性能,但会增加系统复杂性。实现时需将对象成员变量拆分为内在和外在状态,并通过工厂类管理享元对象。
140 83
|
1月前
|
设计模式 数据安全/隐私保护
Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式
这篇文章介绍了在Next.js框架下,如何处理中后台管理系统中特殊页面(如登录页)不包裹根布局(RootLayout)的问题。作者指出Next.js的设计理念是通过布局的嵌套来创建复杂的页面结构,这虽然保持了代码的整洁和可维护性,但对于特殊页面来说,却造成了不必要的布局包裹。文章提出了一个解决方案,即通过判断页面的skipGlobalLayout属性来决定是否包含RootLayout,从而实现特殊页面不包裹根布局的目标。
81 33
|
3月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
53 2
|
4月前
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
47 3
|
5月前
|
设计模式 Java
Java设计模式-享元模式(12)
Java设计模式-享元模式(12)
|
6月前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
6月前
|
设计模式 JavaScript 前端开发
从工厂到单例再到策略:Vue.js高效应用JavaScript设计模式
【8月更文挑战第30天】在现代Web开发中,结合使用JavaScript设计模式与框架如Vue.js能显著提升代码质量和项目的可维护性。本文探讨了常见JavaScript设计模式及其在Vue.js中的应用。通过具体示例介绍了工厂模式、单例模式和策略模式的应用场景及其实现方法。例如,工厂模式通过`NavFactory`根据用户角色动态创建不同的导航栏组件;单例模式则通过全局事件总线`eventBus`实现跨组件通信;策略模式用于处理不同的表单验证规则。这些设计模式的应用不仅提高了代码的复用性和灵活性,还增强了Vue应用的整体质量。
90 1
|
6月前
|
设计模式 JavaScript 前端开发
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
小白请看 JS大项目宝典:设计模式 教你如何追到心仪的女神
|
7月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
109 7
|
7月前
|
设计模式 JavaScript
js设计模式【详解】—— 桥接模式
js设计模式【详解】—— 桥接模式
91 6