资讯专栏INFORMATION COLUMN

设计模式之享元模式

Jioby / 2874人阅读

摘要:而享元模式的核心就是运用共享技术来有效支持大量细粒度的对象。享元模式要求将对象的属性划分为内部状态和外部状态,所以在了解享元模式之前我们先要了解两个概念内部状态外部状态。一般情况下在这四种情况下应该考虑使用享元模式。

享元模式(flyweight)是一种用于性能优化的模式,之所以用“fly”其意为蝇量级。而享元模式的核心就是运用共享技术来有效支持大量细粒度的对象。虽然面向对象可以非常方便的解决一些扩展性的问题,但是在这个过程中系统势必会产生一些类或者对象,如果系统中存在对象的个数过多时,将会导致系统的性能下降。对于这样的问题解决最简单直接的办法就是减少系统中对象的个数。在javascript中,浏览器特别是移动端的浏览器分配的内存并不多,在这种情况下,节省内存就变得十分重要了。

享元模式的定义

所谓享元模式就是运行共享技术有效地支持大量细粒度对象的复用系统使用少量对象,而且这些都比较相似,状态变化小,可以实现对象的多次复用。
享元模式要求将对象的属性划分为内部状态和外部状态,所以在了解享元模式之前我们先要了解两个概念:内部状态、外部状态。

内部状态

在享元对象内部不随外界环境改变而改变的共享部分。
内部属性通常来说应该具备一下几条特性。

内部状态存储于对象内部。

内部状态可以被一些对象共享。

内部状态独立于具体的场景,通常不会改变。

外部状态

外部状态取决于具体的业务场景,并根据场景而变化,不可以共享的状态。一个外部状态与另一个外部状态之间是相互独立的。

由于享元模式区分了内部状态和外部状态,所以我们可以通过设置不同的外部状态使得相同的对象可以具备一些不同的特性,而内部状态设置为相同部分。在我们的程序设计过程中,我们可能会需要大量的细粒度对象来表示对象,如果这些对象除了几个参数不同外其他部分都相同,这个时候我们就可以利用享元模式来大大减少应用程序当中的对象。如何利用享元模式呢?这里我们只需要将他们少部分的不同的部分当做参数移动到类实例的外部去,然后再方法调用的时候将他们传递过来就可以了。

享元模式的使用

假设我们要生产n辆汽车,我们在不用享元模式的情况下,可能会这样

function Car(wheel, price,seat, color, logo) {
    this.wheel = wheel
    this.price = price
    this.seat = seat
    this.color = color
    this.brand = logo
}

然后我们就可以为所欲为了。

var car 1 = new Car(x, x, x, x, x)
var car 2 = new Car(x, x, x, x, x)
var car 3 = new Car(x, x, x, x, x)
...............................
var car 1000 = new Car(x, x, x, x, x)

当我们对象实例化次数过多,就会导致内存无限制的增长,性能可想而知。那么怎么样避免这样的情况出现呢。这里就要用到了享元模式。

var flyWight  = (function(){
    // 这里是存储器,用存储所有的car对象
    var Cars = {}
    var Car = function(d) {
        this.wheel = d.wheel
        this.price = d.price
        this.color = d.color
        this.seat = d.seat
    }
    // 以logo(品牌)为类构建Car类别
    var _factory = function(d) {
        if(!Cars[d.logo]) {
            Cars[d.logo] = new Car(d)
        }
        //返回该品牌的类别
        return Cars[d.logo]
    }

    var carItem =  {
        allCars : {},
        //添加一辆车
        addCar : function(data) {
            if(this.allCars[data.id]) return this.allCars[data.id]
            this.allCars[data.id] = {
                id : data.id,
                logo : data.logo,
                car : _factory(data)
            }
        },
    }
    return carItem
})()

var data = [
    { id: 1, wheel: 4, price: 50000, color: "red", logo: "benz", seat: 8 },
    { id: 2, wheel: 4, price: 40000, color: "blue", logo: "bmw", seat: 4 },
    { id: 3, wheel: 4, price: 50000, color: "red", logo: "ford", seat: 2 },
]
for(var i = 0; i < data.length; i++) {
    flyWight.addCar(data[i])
}

从以上的代码我们可以看到,利用汽车的品牌作为实例的对象而不是单一的某个汽车。因为品牌再多是不会超过汽车的总数的,所以我们实际上要实例的对象就是十几个甚至是几个对象而已。
享元模式是为解决性能问题而生的模式,是很好的性能优化方案,但是很明显它也会带来一些复杂性的问题。一般情况下在这四种情况下应该考虑使用享元模式。

一个程序中使用了大量的相似对象

由于使用大量的对象造成很大的内存开销

对象的大多数状态都可以变为外部状态

可以用相对较少的对象取代大量对象

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90825.html

相关文章

  • 每天一个设计模式享元模式

    摘要:作者按每天一个设计模式旨在初步领会设计模式的精髓,目前采用和两种语言实现。享元模式提醒我们将一个对象的属性划分为内部和外部状态。 作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) 个人技术博客-godbmw.com 欢迎来玩! 每周至少 1 篇原创...

    jone5679 评论0 收藏0
  • 每天一个设计模式享元模式

    摘要:作者按每天一个设计模式旨在初步领会设计模式的精髓,目前采用和两种语言实现。享元模式提醒我们将一个对象的属性划分为内部和外部状态。 作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) 个人技术博客-godbmw.com 欢迎来玩! 每周至少 1 篇原创...

    ormsf 评论0 收藏0
  • 设计模式享元模式

    摘要:类图相关的设计模式享元模式和代理模式当代理模式消耗性能比较大的时候,就可以用享元模式享元模式和单例模式容器单例,享元模式就是复用对象的思想。源码中的享元模式源码地址享元模式参考慕课网设计模式精讲设计模式读书笔记享元模式 0x01.定义与类型 定义:提供了减少对象数量从而改善应用所需的对象结构的方法,系统使用少量对象,而且这些都比较相似,状态变化小,可以实现对象的多次复用。 运用共享技...

    vvpale 评论0 收藏0
  • javascript享元模式

    摘要:享元模式享元模式是一种优化程序性能的模式本质为减少对象创建的个数。 享元模式 享元模式是一种优化程序性能的模式, 本质为减少对象创建的个数。 以下情况可以使用享元模式:有大量相似的对象, 占用了大量内存对象中大部分状态可以抽离为外部状态 demo某商家有 50 种男款内衣和 50 种款女款内衣, 要展示它们 方案一: 造 50 个塑料男模和 50 个塑料女模, 让他们穿上展示, 代码如...

    BlackHole1 评论0 收藏0
  • JavaScript设计模式之结构型设计模式

    摘要:享元模式通过分析应用程序的对象,将其解析为内在数据和外在数据,减少对象数量,从而提高程序的性能。通过这种方式进行事件绑定,可以减少事件处理程序的数量,这种方式叫做事件委托,也是运用了享元模式的原理。事件处理程序是公用的内在部分,每个菜单项各 github 全文地址 : YOU-SHOULD-KNOW-JS JavaScript设计模式之外观模式 概念 外观模式:为一组复杂子系统接口提...

    xiaoqibTn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<