Flyweight
動機
- 採用純粹對象方案的問題在於大量細粒度的對象會很快充斥在系統中,從而帶來很高的運行時代價——主要指內存需求方面的代價。
- 如何在避免大量細粒度對象問題的同時,讓外部客戶程序仍然能夠透明地使用面向對象的方式來進行操作?
模式定義
運行共享技術有效地支持大量細粒度的對象。 ——《設計模式》GoF
(共享技術是面向對象中經常解決性能問題的一種手段;一些對象在編譯器裏也會被進行享元優化到對象池、字符串池裏)
要點總結
- 面向對象很好地解決了抽象性的問題,但是作爲yield運行機器中的程序實體,我們需要考慮對象的代價問題, Flyweight主要解決面向對象的代價問題,一般不觸及面向對象的抽象性問題。
- Flyweight採用對象共享的做法來降低系統中對象的個數,從而降低細粒度對象給系統帶來的壓力。在具體實現方面,要注意對象狀態的處理(儘量保持只讀)。
- 對象的數量太大從而導致對象內存開銷加大——什麼樣的數量纔算大?這需要我們仔細的根據具體應用情況進行評估,而不能憑空臆斷。
Demo
flyweight.cpp:
class Font {
private:
//unique object key
string key;
//object state
//....
public:
Font(const string& key){
//...
}
};
ß
class FontFactory{
private:
map<string,Font* > fontPool; //字體池(對象池)
public:
Font* GetFont(const string& key){
map<string,Font*>::iterator item=fontPool.find(key);
if(item!=footPool.end()){
return fontPool[key];
}
else{
Font* font = new Font(key);
fontPool[key]= font; //同一鍾key,永遠在系統裏只有一個字體對象想對應
return font;
}
}
void clear(){
//...
}
};