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())

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

原文地址:https://www.cnblogs.com/winderby/p/4329805.html