zoukankan      html  css  js  c++  java
  • [设计模式] 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'); }

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

    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;
    }
    
    FlyweightFactory.prototype.getComposite = function(list) {
        var unFly = new UnShareFlyweight();
        var flyweight, state;
        for (idx in list) {
            state = list[idx];
            flyweight = this.getFlyweight(state);
            unFly.add(state, flyweight);
        }
    }
    
    FlyweightFactory.prototype.print = function() {
        var jsons = this.hash.getJson();
        for (json in jsons) {
            json.value.operate();
        }
    }

     3. Client 使用:

    var states = ['AABB', 'CDCD', 'AABB', 'CCDD'];
    
    var factory = new FlyweightFactory();
    factory.getComposite(states);
    
    factory.print();

    输出: 

    AABB-0.8749617566354573

    CDCD-0.6991151459515095

    CCDD-0.9891050879377872

    享元模式其他说明 

    总体来说,享元模式用于减少对象的重复创建,用于减少内存使用,提升性能的结构型模式:

    它涉及三个模式:享元模式,工厂模式,组合模式;

    对于处理多对多对应而产生的一些数据缓存存储,是一个不错的选择!

  • 相关阅读:
    vue绑定值与字符串拼接两种写法
    cmd 总是很卡,执行一条指令就卡死
    生产工具vscode
    js 关于 array 的相关操作––
    webAssembly
    github上fork别人的分支到目录下  
    68.Promise和setTimeout的区别
    67、Promise 构造函数是同步执行还是异步执行,那么 then 方法呢?
    66、深入理解 promise:promise的三种状态与链式调用
    65.ES6新的特性有哪些?
  • 原文地址:https://www.cnblogs.com/editor/p/4262880.html
Copyright © 2011-2022 走看看