iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 10
0
Modern Web

JS Design Pattern 系列 第 10

JS Design Pattern Day10-輕量模式 Flyweight(上)

Hey大家好,今天第10天啦,這次又分上下集來寫了。偷懶其實是為了走更長遠的路。

今天 輕量模式(上)

輕量模式是一種用於效能最佳化的模式,如果系統建立了大量相似的物件導致佔用過多記憶體,使系統效能降低,
那我們就必須要節省記憶體的使用,輕量模式就是解決類似問題的一種模式。

實際舉一個例子,假設有個賣衣服的廠商,目前推出50種男士上衣與50種女士上衣,為了推銷需要拍照展示。
在不使用輕量模式的狀況下或許會這寫:
先建立Model建構函數,內容要指定model的性別以及要穿的衣服

var Model = function(gender, clothes) {
	this.gender = gender;
	this.clothes = clothes;
};

建立拍照功能

Model.prototype.takePhoto = function() {
	console.log('gender=' + this.gender + ' clothes=' + this.clothes);
};

開始拍照啦

for (var i = 1; i <= 50; i++) {
	var maleModel = new Model('male', 'clothes' + i);
	maleModel.takePhoto();
}

for (var i = 1; i <= 50; i++) {
	var femaleModel = new Model('female', 'clothes' + i);
	femaleModel.takePhoto();
}

照上述狀況,總共就會產生100個物件,若將來衣服總數增加那麼物件總數也會隨之增加。

我們可以試著最佳化這個場景,雖然衣服有100件,但其實我們只需要兩位model也就是只要有兩個model物件就好:
其實model只需要區別男女,所以先移除構造函數裡的clothes物件

var Model = function(gender, clothes) {
	this.gender = gender;
};

一樣的拍照功能

Model.prototype.takePhoto = function() {
	console.log('gender=' + this.gender + ' clothes=' + this.clothes);
};

接下來實際分別建立男女model物件,各一個

var maleModel = new Model('male');
var femaleModel = new Model('femaleModel');

然後每次拍照,再給model換穿上衣服

for (var i = 1; i <= 50; i++) {
	maleModel.clothes = 'clothes' + i;
	maleModel.takePhoto();
}

for (var i = 1; i <= 50; i++) {
	femaleModel.clothes = 'clothes' + i;
	femaleModel.takePhoto();
}

經過改造之後,可以發現其實用兩個物件就可以替代原本的方法,並完成相同功能。

這個例子就是輕量模式的雛形,輕量模式要求將物件的屬性分為'內部'與'外部'兩種狀態(屬性),至於要如何劃分呢?
作者也提供了一些指引:
1.內部狀態儲存於物件內部
2.內部狀態可以被一些物件共享
3.內部狀態獨立於具體場景,通常不會改變
4.外部狀態取決於具體場景,並根據場景而變化,外部狀態不能被共享

在這個範例中,性別(gender)就是內部狀態,而外部狀態則是衣服(clothes),我們就可以將相同內部狀態的物件共用(所有性別都是男生的model共用,就只需要一個物件),外部狀態可以從物件身上抽離出來(Model建構函數中已經沒有clothes屬性),並儲存在外部,而外部物件會跟劇場景而變化,所以沒有辦法共享。

抽離外部狀態之後的model物件就可以被共用,需要用到外部狀態的時候再被傳入並設置,雖然這樣做會多花一些時間,但就以這個例子來說其實是非常值得的。因此也可以說輕量模式是一種時間換空間的作法。通常來說內部狀態有多少種組合,系統就會最多存在多少物件。

以上範例還存在一些問題:
1.一開始就new出兩個model物件,但在有些系統之中並不是一開始就需要有所有的共享物件。
2.給model物件手動設置了clothes外部狀態,在較複雜的系統中這不是一個最好的方式,因外部狀態可能會相當複雜,他們與共享物件的聯繫會變得困難。

我們下集將會來提出方法解決這兩個問題。


上一篇
JS Design Pattern Day09-範本方法模式 TemplateMethod
下一篇
JS Design Pattern Day11-輕量模式 Flyweight(下)
系列文
JS Design Pattern 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言