[設計模式] javascript 之 享元模式;

享元模式說明數據庫

定義:用於解決一個系統大量細粒度對象的共享問題:json

關健詞:分離跟共享;緩存

說明: 享元模式分單純(共享)享元模式,以及組合(不共享)享元模式,有共享跟不共享之分;單純享元模式,只包含共享的狀態,可共享狀態是不可變,不可修改的,這是享元的內部狀態;固然有外部狀態就有外部狀態,外部狀態是可變的,不被共享,這個外部狀態由客戶端來管理,是可變化的;外部狀態與內部狀態是獨立分開的,外部狀態通常做爲參數傳入享元對象內,但不會影響內部狀態的值;外部狀態,一用用於獲取共享的享元對象,或多或少與內部狀態有點關聯;好比從用戶數據表中獲取數據,傳入一個外部變量用戶名,再根據這個用戶名,獲取該用戶全部對象狀態信息;dom

組合享元模式,配置組合模式來使用,共享部分只作個葉子節點,而組合部分是沒必要共享的,由於共組部分的子葉節點元素已經被緩存,組合部分至關一個分組分類的做用;性能

享元模式通常會與工廠模式相結合使用,用於管理緩存的建立跟維護,享元共享元素的建立通常在工廠類裏建立;優化

享元模式主要用於對象的共享,使具備類似對象,或對象間具備太多類似細粒度的狀態,能共享已經建立的對象,減小對象的建立,減小對內存的佔用,提高優化性能;this

一種場景:spa

 

享元模式結構圖:prototype

 

像第一張的狀況,就可使用享元模式,由於後兩排的狀態組合,可能在實體對應中,屢次存在,這時就可使用享元的共享特性,來減小對象的建立,若有相同的狀態或組合,就能夠獲取緩存的狀態,減小對象重複建立,減小內存佔用;code

實例場景:

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

享元模式其餘說明 

整體來講,享元模式用於減小對象的重複建立,用於減小內存使用,提高性能的結構型模式:

它涉及三個模式:享元模式,工廠模式,組合模式;

對於處理多對多對應而產生的一些數據緩存存儲,是一個不錯的選擇!

相關文章
相關標籤/搜索