zoukankan      html  css  js  c++  java
  • javascript模式——Flyweight

    Flyweight是一种共享数据内存的模式。

    Flyweight模式是将一些公有属性从个人中剔除,放在共享的对象当中。

    下面以一个项目实例,通过不断的改进,以显示Flyweight模式的优点。

    现在我们想做一个电脑生产程序,用以生产电脑,电脑的一般有生产商,机型,CPU类型,内存,和型号。

    我们的最初代码如下:

    // 电脑类
    var Computer = function (make, model, processor, memory, tag) {
        this.make = make;
        this.model = model;
        this.processor = processor;
        this.memory = memory;
        this.tag = tag;
    }
    
    // 测试生产两台不同的电脑
    var computer1 = new Computer("Dell", "Studio XPS", "Intel", "4G", "Y755P");
    var computer2 = new Computer("Dell", "Studio XPS", "Intel", "8G", "Y755P");
    
    console.log(computer1); 
    console.log(computer2);

     对代码简单的分析,我们可以发现,两台不同的电脑的前三个属性,品牌,机型和CPU都是一样的。而我们却每次都为其重新定义赋值。

    试想一下,如果这样有一百上千台的电脑,那对内存来说就是一笔不小的开销。我们可不可以将这些相同的属性共有化呢?

    // 电脑类
    var Computer = function (make, model, processor, memory, tag) {
        
        // 引用共享单元中的数据
        if(make + model + processor === "DellStudio XPSIntel"){
            this.flyweight = flyweight1;
        }
        this.memory = memory;
        this.tag = tag;
    }
    
    // 共享单元
    var flyweight = {
        make: 'Dell', 
        model: "Studio XPS", 
        processor: "Intel"
    }
    
    // 测试
    var computer1 = new Computer("Dell", "Studio XPS", "Intel", "4G", "Y755P");
    var computer2 = new Computer("Dell", "Studio XPS", "Intel", "8G", "Y755P");
    
    console.log(computer1);
    console.log(computer2);

    在这里我们将共有几乎固定的属性从类中剔除,建立了一个很生硬的对象flyweight以存放他们用来共享。就这样,虽然新生产每台电脑都有5个属性,但其中前三个属性都是共享flyweight对象中的数据。节省了内存开支。尤其这样前三个属性相同的电脑比较多时,这已经就是Flyweight的精髓了,只是我们的模式还很初步。

    继续我们的思路,如果我们需要再多一个共享单元呢,难道重新创建一个对象?不是的。此时我们用一个类创建各种享元,且用一个对象作为列表来存放来会更好一些。

    // 享元列表
    var flyweightList = {};
    
    var Computer = function (make, model, processor, memory, tag) {
        
        if(flyweightList[make+model+processor]){
            
            // 享元列表中存在,直接引用
            this.flyweight = flyweightList[make+model+processor];
        }else {
            
            // 不存在,创建新的享元对象并存入列表中
            this.flyweight = new Flyweight(make, model, processor);
            flyweightList[make+model+processor] = this.flyweight;
        }
        
        this.memory = memory;
        this.tag = tag;
    }
    
    // 享元类
    function Flyweight (make, model, processor) {
        
        this.make = make;
        this.model = model;
        this.processor = processor;
        
    };
    
    
    var computer1 = new Computer("Dell", "Studio XPS", "Intel", "4G", "Y755P");
    var computer2 = new Computer("Dell", "Studio XPS", "Intel", "8G", "Y755P");
    
    var computer3 = new Computer("HP", "Envy", "Intel", "2G", "801632312");
    
    console.log(computer1);
    console.log(computer2);
    console.log(computer3);

    这样其实已经很不错了,只是享元列表作为一个全局变量似乎不太好,在比较高级的享元模式运用,我们还需要一些其他的方法,如获取享元中的数量等。进一步我们可以用模块模式将享元包裹一下。

    function Flyweight (make, model, processor) {
        
        this.make = make;
        this.model = model;
        this.processor = processor;
        
    };
    
    var FlyweightFactory = (function(){
        
        // 私有
        var flyweightList = {};
        
        return {
            
            // 新增享元
            addFlyweight: function (make, model, processor){
                if(!flyweightList[make+model+processor]){
                    flyweightList[make+model+processor] = new Flyweight(make, model, processor);
                }
                return flyweightList[make+model+processor];
            },
            
            // 计数
            count: function(){
                var count = 0;
                for (var f in flyweightList) count++;
                return count;
            }
        }
    })()
    
    var Computer = function (make, model, processor, memory, tag) {
        
        this.flyweight = FlyweightFactory.addFlyweight(make, model, processor)
        this.memory = memory;
        this.tag = tag;
        
    }
    
    var computer1 = new Computer("Dell", "Studio XPS", "Intel", "4G", "Y755P");
    var computer2 = new Computer("Dell", "Studio XPS", "Intel", "8G", "Y755P");
    var computer3 = new Computer("HP", "Envy", "Intel", "2G", "801632312");
    
    console.log(computer1);
    console.log(computer2);
    console.log(computer3);
    console.log(FlyweightFactory.count())

    享元是一种非常常用的设计模式,对性能的优化有很大的作用。

  • 相关阅读:
    cmd net use
    Linux虚拟机安装VMware Tools
    转:完成端口(Completion Port)详解
    很幽默的讲解六种Socket IO模型
    重新学习二叉树作的几道习题
    RuntimeException和Exception区别
    不同概率的抽奖
    SpringMVC的几种返回方式
    mybatis动态sql trim
    Tomcat 7最大并发连接数的正确修改方法
  • 原文地址:https://www.cnblogs.com/winderby/p/4329805.html
Copyright © 2011-2022 走看看