四个轮子,一个方向盘,有刹车,油门,车窗,这些词首先让人联想到的就是一辆汽车。的确,这些都是是一辆车的最基本特征,或者是属性,我们把词语抽象出来,而听到这些词语的人把他们想象陈一辆汽车。在代码里面也是这样的,为了将所有的车辆统一描述,我们将车的特征抽象出来,作为一个理念,就像柏拉图说的那样,接下来,我们要这个理念描绘他,让人来认识。这也就是程序中的实例化:

function Car() { this.lunzi = 4; this.shache = 1; }//js中没有类概念,但是我们可以模拟出来。这样,Car就作为了构造函数了。

接下来我们来实例它,让柏拉图的理念在现象世界中得到展示:

var benchi = new Car();

benchi 这个变量就是一个实例了。作为一辆汽车,它有四个轮子(lunzi),一个刹车(shache)。但是问题来了:理念只有一个,但是实例有很多,如果实例太多会怎么样呢?就跟起初上帝造物一样,起初只有一个人,后来从亚当身上撤下肋骨一根做了夏娃,夏娃吃了禁果,人类繁衍,人一多,罪恶就多了。程序的世界里也是这样,对象实例化次数过多,会导致内存无限制的增长,性能可想而知。那么怎么样避免这样的情况出现呢?享元模式出现了。下面我们以一个地方的财政系统购买外国车辆为例,运用享元模式解答难题,这个传统的实现方法:

	var Cars = function(id, lt, fxp, lhq, sc, zw, cp, pp, ys, jg, cc, dhy ) {
this.id = id;
this.lt = lt;//轮胎
this.fxp = fxp;//方向盘
this.lhq = lhq;//离合器
this.sc = sc;//刹车
this.zw = zw;//座位
this.cp = cp;//车牌
this.pp = pp;//品牌
this.ys = ys;//颜色
this.jg = jg;//价格
this.cc = d.cc;//车窗
this.dhy = d.dhy;//导航仪
}

接下来的事情很容易,一个一个实例化这个类:

var car 1 = new Car('x',x,x,x,x,x,x,x,x,x);
var car 2 = new Car('x',x,x,x,x,x,x,x,x,x);
var car 3 = new Car('x',x,x,x,x,x,x,x,x,x);
...............................
var car 100 = new Car('x',x,x,x,x,x,x,x,x,x);//终于完了!!!

但是车辆数量一多起来的话会出现内存过多的问题。我们可以看到,一辆车里面有很多属性比如刹车数量,车窗数量,座位数量是相同的,享元模式的核心思想就是把共同享有的基本元素抽象出来。来看看是如何实现的。

//享元模式
var flyWight = (function(window, undefined){//立即执行函数返回一个享元对象
var Cars = {};//这里是存储器,用存储所有的car对象
var Car = function(d) {//构造方法
this.id = d.id;
this.lt = d.lt;//轮胎
this.fxp = d.fxp;//方向盘
this.lhq = d.lhq;//离合器
this.sc = d.sc;//刹车
this.zw = d.zw;//座位
this.cc = d.cc;//车窗
this.dhy = d.dhy;//导航仪
}
Car.prototype.gmg = 'china';// 买家的国籍,这里适应定义一些公共属性,适用于所有车辆的公用属性,比如购买的国家,方便统一修改
Car.prototype = {//Car的原型类方法,上面提供了操作Car实例的一些方法,可以自己定义,卤煮在此只定义最基本的方法
set : function(n ,v) {
this[n] = v;
},
get : function(n) {
return this[v];
}
}
var _factory = function(d) {//构建实例工厂,以pp(品牌)为类构建Car类别,,此方法属于私有,外部无法调用。
if(!Cars[d.pp]) {
Cars[d.pp] = new Car(d);
}
return Cars[d.pp];//返回该品牌的类别
} var controlCar = {//享元对象
allCars : {},//另一个存储所有车辆的对象,
addCar : function(data) {//添加一辆车
if(this.allCars[data.id]) return this.allCars[data.id];
this.allCars[data.id] = {
id : data.id,
pp : data.pp,
ys : data.ys,
cp : data.cp,
buyTime : data.buyTime,
jg : data.jg,
car : _factory(data)
}
},
removeCar : function(data) {//删除一辆车
if(this.allCars[data.id]) {
this.allCars[data.id] = undefined;
}
},
getCar : function (id) {//获取一辆汽车
return this.allCars[id];
}
} return controlCar;//返回享元对象
})(window, undefined);

从以上的代码我们可以看到,利用汽车的品牌作为实例的对象而不是单一的某个汽车。因为品牌再多是不会超过汽车的总数的,所以我们实际上要实例的对象就是十几个甚至是几个对象而已。这样,在allCar所有的子集元素中,每一个都是一辆包含有品牌类别的对象字面量而不是Car的实例对象了,我们可以在Car的原型链中中编写很多方法操作它们,同时它(该对象)不会丧失作为一辆汽车的基本特征,而且还会保持自己私有(颜色,价格)等特征。这样我们就达到了减少实例对象的目的了。下面,我们来看看它们是是怎么被用到的。首先是数据,这里有八辆车,三个品牌的,所以只有有三个Car的实例对象:

var data = [
{id:1,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x1231',pp:'benchi', ys:'red', jg:200000, buyTime : '1999-08-20', cc : 6, dhy : 1},
{id:2,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x1232',pp:'benchi', ys:'black', jg:207000, buyTime : '1999-08-21', cc : 6, dhy : 1},
{id:3,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x1233',pp:'benchi', ys:'gray', jg:200000, buyTime : '1999-08-22', cc : 6, dhy : 1}, {id:4,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x4564',pp:'fute', ys:'yellow', jg:150000, buyTime : '1999-08-23', cc : 6, dhy : 1},
{id:5,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x4565',pp:'fute', ys:'black', jg:160000, buyTime : '1999-08-24', cc : 6, dhy : 1},
{id:6,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x4566',pp:'fute', ys:'gray', jg:109000, buyTime : '1999-08-25', cc : 6, dhy : 1}, {id:7,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x7897',pp:'baoma', ys:'black', jg:380000, buyTime : '1999-08-26', cc : 6, dhy : 1},
{id:8,lt:4,fxp:1,lhq:1,sc:1,zw:5,cp:'x7898',pp:'baoma', ys:'blue', jg:300000, buyTime : '1999-08-27', cc : 6, dhy : 1}
]

轮询通过模式封装:

for(var i=0; i<data.length; i++) {
flyWight.addCar(data[i]);
}

通过flyWight.getCar(id)你可以获得你想要的某一辆车,你可以用直接赋值的方法修改它的特殊属性;

flyWight.getCar('1').jg = 300000

也可以通过Car字段所包含的对象的私有方法处理一些实际上很少会改变的值:

flyWight.getCar('1').car.set('lt', 5)

当然,我们在这里的基础属性并不是私有的,你可以按照自己的想法来编写代码。

总结:享元模式的核心:1有基础单元共享的数据对象集合,2.构造工厂函数,3.存储实例对象的容器。你可以在基本思想上面发挥自己的想法,这里例举的只是一个很简单的例子。

javascript 设计模式-----享元模式的更多相关文章

  1. 读书笔记之 - javascript 设计模式 - 享元模式

    本章探讨另一种优化模式-享元模式,它最适合于解决因创建大量类似对象而累及性能的问题.这种模式在javascript中尤其有用,因为复杂的javascript代码很快就会用光浏览器的所有可用内存,通过把 ...

  2. javascript设计模式——享元模式

    前面的话 享元(flyweight)模式是一种用于性能优化的模式,“fly”在这里是苍蝇的意思,意为蝇量级.享元模式的核心是运用共享技术来有效支持大量细粒度的对象.如果系统中因为创建了大量类似的对象而 ...

  3. javascript设计模式-享元模式

    享元模式采用一个共享来有效的支持大量细小粒度的对象,避免大量有相同内容的类的开销(如内存耗费),共享一个元类. 应用场景:页面存在大量的资源密集型对象:他们具备一些共性,可以分离出公共操作的数据. 一 ...

  4. 8. 星际争霸之php设计模式--享元模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  5. C++设计模式——享元模式

    本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.如果这篇文章对你有帮助,你可以请我喝杯咖啡. » 本文链接:http:// ...

  6. java设计模式——享元模式

    一. 定义与类型 定义:提供了减少对象数量从而改善应用所需的对象结构的方式,运用共享技术有效地支持大量细粒度的对象 类型:结构性 二. 使用场景 (1)  常常应用于系统底层的开发,以便解决系统的性能 ...

  7. 【设计模式】Java设计模式 - 享元模式

    Java设计模式 - 享元模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...

  8. [设计模式] javascript 之 享元模式;

    享元模式说明 定义:用于解决一个系统大量细粒度对象的共享问题: 关健词:分离跟共享: 说明: 享元模式分单纯(共享)享元模式,以及组合(不共享)享元模式,有共享跟不共享之分:单纯享元模式,只包含共享的 ...

  9. [工作中的设计模式]享元模式模式FlyWeight

    一.模式解析 Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意.享元模式是对象的结构模式.享元模式以共享的方式高效地支持 ...

随机推荐

  1. oracle 体系结构

    oracle 体系结构 数据库的体系结构是指数据库的组成.工作过程与原理,以及数据在数据库中的组织与管理机制. 1. oracle工作原理: 1).在数据库服务器上启动Oracle实例:2).应用程序 ...

  2. ActionBarSherlock环境搭建

    1.在官网http://actionbarsherlock.com/下载ActionBarSherlock包解压到. 2.创建自己的Android工程: 3.File -> New ->  ...

  3. Winform主窗体设计

    主窗体顶部为菜单按钮,子窗体内嵌入Panel显示 界面如下: 第二步,主窗体离不开的几个方法 1,点击菜单功能,加载子窗体 private void btnOpenForm_Click(object ...

  4. [OSI]网络7层模型的理解

    应用层:HTTP 应用层 表现层:编码 表现层 会话层:端口 会话层 传输层:TCP/UDP 协议 传输层 网络层:IP 标记  +-- 网络层 --+  网络层 数据链路层:计算机Mac地址标记 | ...

  5. [php-src]Php扩展的多文件编译

    内容均以php5.6.14为例. 假设有模块 foo,php_foo.h 和 foo.c 是固有文件,额外的C文件如果要加入编译,大致有五步. 1. 新增头文件 foo_bar.h #ifndef F ...

  6. DOCTYPE的详细图解

    之前有一次写代码的时候忘记写了<!DOCTYPE html> 导致样式的效果一直有点问题,查了很久才发现时候这个的锅.之后自己详细的来查找了DOCTYPE的作用. 在目前,基本上都是采用浏 ...

  7. java UDP

    UDP 与 tcp 连接的 区别 以及  两者的不同 UDp 1 面向的是无连接的网络方式 2 传输速度快 (但是容易发生丢包 ) 3 传输的数据的大小带有的限制 一般是在64k  范围内 tcp 1 ...

  8. 注册表信息(安装包ProductCode,设置启动运行)

    一.获取安装包ProductCode后,再获取安装包DisplayVersion,比对安装包版本,确定是否更新当前应用(重新下载安装包,并运行安装包) //获取当前应用程序的安装包的ProductCo ...

  9. mysql 事件调度

    适用于mysql 5.1 及以后版本 1.查看是否开启 show variables like '%scheduler%' 2.查看进程 show processlist 3.事件调度器默认是关闭的, ...

  10. js动态时间

    一.在<head></head> 之间写入下面js代码 <script type="text/javascript" language="J ...