javascript 设计模式之享元模式原理与应用详解

定义:用于解决一个系统大量细粒度对象的共享问题:

关健词:分离跟共享;

说明: 享元模式分单纯(共享)享元模式,以及组合(不共享)享元模式,有共享跟不共享之分;单纯享元模式,只包含共享的状态,可共享状态是不可变,不可修改的,这是享元的内部状态;当然有外部状态就有外部状态,外部状态是可变的,不被共享,这个外部状态由客户端来管理,是可变化的;外部状态与内部状态是独立分开的,外部状态一般作为参数传入享元对象内,但不会影响内部状态的值;外部状态,一用用于获取共享的享元对象,或多或少与内部状态有点关联;比如从用户数据表中获取数据,传入一个外部变量用户名,再根据这个用户名,获取该用户所有对象状态信息;

组合享元模式,配置组合模式来使用,共享部分只做个叶子节点,而组合部分是不必共享的,因为共组部分的子叶节点元素已经被缓存,组合部分相当一个分组分类的作用;

享元模式一般会与工厂模式相结合使用,用于管理缓存的创建跟维护,享元共享元素的创建一般在工厂类里创建;

享元模式主要用于对象的共享,使具有相似对象,或对象间具有太多相似细粒度的状态,能共享已经创建的对象,减少对象的创建,减少对内存的占用,提升优化性能;

一种场景:

享元模式结构图:

像第一张的情况,就可以使用享元模式,因为后两排的状态组合,可能在实体对应中,多次存在,这时就可以使用享元的共享特性,来减少对象的创建,如有相同的状态或组合,就可以获取缓存的状态,减少对象重复创建,减少内存占用;

实例场景:

1>. 系统各种角色权限分配;

2>. 系统出现很多种状态,或组合状态需要对应的,而且这种对应,可以发生很多种其他类型对象上面的,就可以使用享元模式;

实例源码: 单纯(共享)享元

1. 自定义的 JavaScript Hashtable:

function Hashtable() { this.values = []; } Hashtable.prototype.getJson = function() {   return this.values; } Hashtable.prototype.add = function(key, value) { if (!this.contain(key)) { this.values.push({key:key, value:value}); } } Hashtable.prototype.contain = function(key) { for (idx in this.values) { var json = this.values[idx]; if (json.key == key) { return true; } } return false; } Hashtable.prototype.get = function(key) { var result; for (idx in this.values) { var json = this.values[idx]; if (json.key == key) { result = json; break; } } return result; } Hashtable.prototype.delete = function(key) { for (idx in this.values) { var json = this.values[idx]; if (json.key == key) { delete this.values[idx]; break; } } } Hashtable.prototype.set = function(key, value) { if (this.contain(key)) { this.delete(key); this.values.push({key:key,value:value}); } }

2. 享元方法:

function Flyweight(one) { this.stateOne = one; } Flyweight.prototype.operate = function(){    var date = new Date(); console.log(this.stateOne + '-' + Math.random()); };

这里可以处理传进来的参数的一些逻辑,也可以初始化从数据库里提取数据缓存保存;

3. 享元工厂:

function FlyweightFactory(){ var hash = new Hashtable(); } FlyweightFactory.prototype.getFlyweight = function(state) { var flyweight; if (hash.contain(state)) { flyweight = hash.get(state); } else { flyweight = new Flyweight(state); hash.add(state, flyweight); } return flyweight; }

4. Client 使用:

//Client var factory = new FlyweightFactory(); var fly1, fly2, fly3; fly1 = factory.getFlyweight('AABB'); fly2 = factory.getFlyweight('CCDD'); fly3 = factory.getFlyweight('CCDD'); fly1.operate(); fly2.operate(); fly3.operate();

输出:

AABB-0.8621504916809499

CCDD-0.7498800195753574

CCDD-0.7498800195753574

复合享元模式

1. 复合享元

function UnShareFlyweight() { this.state = ''; this.hash = new Hashtable(); } UnShareFlyweight.prototype.add = function(key, flyweight) { this.hash.add(key, flyweight); } UnShareFlyweight.prototype.operate = function(state) { var flag = false;    /* for (idx in this.hash) { var fly = this.list[idx]; if (fly.stateOne == state) { flag = true;        break; } }   */       flag = this.hash.contain(state); flag ? console.log('Exists') : console.log('Not Exists'); }

2. 在修改添加在享元工厂的组合方法:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/86318017e09869ff7a99d7354e260101.html