1. 程式人生 > 程式設計 >javascript設計模式 – 享元模式原理與用法例項分析

javascript設計模式 – 享元模式原理與用法例項分析

本文例項講述了javascript設計模式 – 享元模式原理與用法。分享給大家供大家參考,具體如下:

介紹:在我們日常開發中需要建立很多物件,雖然垃圾回收機制能幫我們進行回收,但是在一些需要重複建立物件的場景下,就需要有一種機制來進行優化,提高系統資源的利用率。

享元模式就是解決這類問題,主要目的是減少建立物件的數量。享元模式提倡重用現有同類物件,如未找到匹配的物件則建立新物件

定義:運用共享技術有效的支援大量細粒度物件的複用。系統只適用少量的物件,而這些物件都很相似,狀態變化很小,可以實現物件的多次複用。由於享元模式要求能夠共享的物件必須是細粒度的物件,因此他又稱為輕量級模式,是一種物件結構型模式。

場景:我們以建立圓形物件為例,通過兩個例子來對比享元模式的效果。

示例:

var redCricle = new Circle('red');
redCricle.setAttr(10,10,10);
redCricle.draw();
 
var redCricle1 = new Circle('red');
redCricle1.setAttr(1,1,100);
redCricle1.draw();
 
var redCricle2 = new Circle('red');
redCricle2.setAttr(5,5,50);
redCricle2.draw();
 
var blueCricle = new Circle('blue');
blueCricle.setAttr(1,50);
blueCricle.draw();
 
var blueCricle1 = new Circle('blue');
blueCricle1.setAttr(12,12,50);
blueCricle1.draw();
 
var blueCricle2 = new Circle('blue');
blueCricle2.setAttr(2,20);
blueCricle2.draw();
// 建立了一個物件
// 畫圓: 顏色:red x:10 y:10 radius:10
// 建立了一個物件
// 畫圓: 顏色:red x:1 y:1 radius:100
// 建立了一個物件
// 畫圓: 顏色:red x:5 y:5 radius:50
// 建立了一個物件
// 畫圓: 顏色:blue x:1 y:1 radius:50
// 建立了一個物件
// 畫圓: 顏色:blue x:12 y:12 radius:50
// 建立了一個物件
// 畫圓: 顏色:blue x:2 y:12 radius:20

這種情況下每次使用都需要例項化一次Circle物件,對系統資源來說是一種浪費。

觀察下不難發現,除了第一次需要例項化,其餘的可以基於例項繼續修改。

我們修改下:

var Circle = function(color){
  console.log('建立了一個物件');
  this.color = color;
  this.x;
  this.y;
  this.radius;
 
  this.setAttr = function(x,y,radius){
    this.x = x;
    this.y = y;
    this.radius = radius;
  }
  this.draw = function(){
    console.log('畫圓: 顏色:' + this.color + ' x:' + this.x + ' y:' + this.y + ' radius:' + this.radius)
  }
}
 
var ShapeFactory = function(){
  this.circleMap = {};
  this.getCircle = function(color){
    var circle = this.circleMap[color];
    if(!circle){
      circle = new Circle(color);
      this.circleMap[color] = circle;
    }
    return circle;
  }
}
var factory = new ShapeFactory();
 
var redCricle = factory.getCircle('red');
redCricle.setAttr(10,10);
redCricle.draw();
 
var redCricle1 = factory.getCircle('red');
redCricle1.setAttr(1,100);
redCricle1.draw();
 
var redCricle2 = factory.getCircle('red');
redCricle2.setAttr(5,50);
redCricle2.draw();
 
var blueCricle = factory.getCircle('blue'); 
blueCricle.setAttr(1,50);
blueCricle.draw();
 
var blueCricle1 = factory.getCircle('blue');
blueCricle1.setAttr(12,50);
blueCricle1.draw();
 
var blueCricle2 = factory.getCircle('blue');
blueCricle2.setAttr(2,20);
blueCricle2.draw();
 
// 建立了一個物件
// 畫圓: 顏色:red x:10 y:10 radius:10
// 畫圓: 顏色:red x:1 y:1 radius:100
// 畫圓: 顏色:red x:5 y:5 radius:50
// 建立了一個物件
// 畫圓: 顏色:blue x:1 y:1 radius:50
// 畫圓: 顏色:blue x:12 y:12 radius:50
// 畫圓: 顏色:blue x:2 y:12 radius:20

我們通過一個工廠來動態建立Circle物件,將例項進行儲存,儲存的位置稱之為享元池。第二次建立時,直接使用已有的結果。節約了系統資源

享元模式總結:

優點:
* 大大減少物件的建立,降低系統記憶體使用,使效率提高。
* 享元模式外部狀態獨立,不會影響其內部狀態,使得享元物件可以在不同環境被共享。

缺點:
* 提高了系統複雜度,且需要相同的屬性,否則會造成系統混亂

適用場景:
* 一個系統有大量相同或相似的物件,造成記憶體大量耗費。
* 物件大部分狀態都可以外部化
* 在使用享元模式時需要維護一個儲存享元物件的享元池,而這需要耗費一定的系統資源。因此使用時要衡量。

感興趣的朋友可以使用線上HTML/CSS/JavaScript程式碼執行工具:http://tools.jb51.net/code/HtmlJsRun測試上述程式碼執行效果。

更多關於JavaScript相關內容感興趣的讀者可檢視本站專題:《javascript面向物件入門教程》、《JavaScript錯誤與除錯技巧總結》、《JavaScript資料結構與演算法技巧總結》、《JavaScript遍歷演算法與技巧總結》及《JavaScript數學運算用法總結》

希望本文所述對大家JavaScript程式設計有所幫助。