Linux C++ 052-設計模式之享元模式
本節關鍵字:Linux、C++、設計模式、享元模式
相關庫函數:
概念
享元模式(FlyWeight),運用共享技術有效的支持大量細粒度的對象。
典型的享元模式的例子為文書處理器中以圖形結構來表示字符。一個做法是,每個字形有其字型外觀, 字模 metrics,和其它格式資訊,但這會使每個字符就耗用上千字節。取而代之的是,每個字符參照到一個共享字形物件,此物件會被其它有共同特質的字符所分享;只有每個字符(文件中或頁面中)的位置才需要另外儲存。
使用場景
兩個狀態
內蘊狀態存儲在享元內部,不會隨環境的改變而有所不同,是可以共享的。
外蘊狀態是不可以共享的,它隨環境的改變而改變的,因此外蘊狀態是由客戶端來保持(因為環境的變化是由客戶端引起的)。
如果一個應用程序使用了大量的對象,而這些對象造成了很大的存儲開銷的時候就可以考慮是否可以使用享元模式。
例如,如果發現某個對象的生成了大量細粒度的實例,并且這些實例除了幾個參數外基本是相同的,如果把那些共享參數移到類外面,在方法調用時將他們傳遞進來,就可以通過共享大幅度單個實例的數目。
角色說明
1、抽象享元角色:為具體享元角色規定了必須實現的方法,而外蘊狀態就是以參數的形式通過此方法傳入。在Java中可以由抽象類、接口來擔當。
2、具體享元角色:實現抽象角色規定的方法。如果存在內蘊狀態,就負責為內蘊狀態提供存儲空間。
3、享元工廠角色:負責創建和管理享元角色。要想達到共享的目的,這個角色的實現是關鍵!
4、客戶端角色:維護對所有享元對象的引用,而且還需要存儲對應的外蘊狀態。
代碼示例
// 運用共享技術(享)有效地支持大量細粒度(元)的對象。在有大量的對象時,把其中共有的部分抽象出來,如果有相同的業務請求時,直接返回內存中已有的對象,避免重新創建
// 享元模式的使用情況:
// 系統中有大量的對象,消耗大量的內存,且這些對象的狀態可被外部化
// 對于享元模式,對象的信息分為兩個部分:內部狀態和外部狀態
// 內部狀態:指被共享出來的信息,存儲在享元對象的內部,且不隨環境改變
// 外部狀態:不可共享,隨環境改變而改變,有客戶端來控制
//
// 享元類接口
class WebSite
{
public:virtual void use() = 0;
};
// 具體的享元類
class ConcreteWebSite : public WebSite
{
private:string name;
public:ConcreteWebSite(string name) {this->name = name;}void use() {cout << "website catagory: " << endl;}
};
// 享元工廠
class WebSiteFactory
{
private:map<string, WebSite*> wf;
public:WebSite* getWebSiteCategory(string key) {if (wf.find(key) == wf.end()) {wf[key] = new ConcreteWebSite(key);}return wf[key];}int getWebSiteCount() {return wf.size();}
};
int main_WebSite()
{WebSiteFactory* wf = new WebSiteFactory();WebSite* fx = wf->getWebSiteCategory("good");fx->use();WebSite* fy = wf->getWebSiteCategory("present");fy->use();WebSite* fz = wf->getWebSiteCategory("present");fz->use();cout << wf->getWebSiteCount() << endl;return 0;
}
/* 運行結果: 上述代碼中,我們發現相同的對象將不再創建,直接使用之前已有的
website catagory: good
website catagory: present
website catagory: present
website catagory: blog
website catagory: blog
3
*/