1. 程式人生 > >享元模式及C++實現

享元模式及C++實現

享元模式(flyweight)

flyweight是輕量級的意思,中文這邊翻譯成享元,更容易讓人理解一些。

享元模式是為了應對大量細粒度物件重複的問題。程式中存在大量細粒度的物件,每次要使用時都必須建立一個新的物件,既影響了執行效率又增加了記憶體消耗。於是有了享元模式,享元模式提取出這些細粒度物件中間公共的狀態(屬性,我的理解),只生成一個例項物件,所有用到這些公共屬性物件的地方,都指向這一個例項。

根據我的理解,很多類有一部分的屬性是可以共享的,而不可共享的部分需要提取出來,通過引數傳遞來使用。

典型的享元模式的例子為文書處理器中以圖形結構來表示字元。一個做法是,每個字形有其字型外觀,字模metrics,和其他格式資訊,但為每個字元都生成這些書寫,就會額外消耗許多的記憶體空間。取而代之的是,每個字元參照一個共享字形物件,此物件會被其他有共同特質的字元所分享;只有每個字元的位置才需要另外儲存。[摘自 維基百科-享元模式]

文書處理器是最普遍的用來說明享元模式的例子。從這個例子就能看到哪些是可以被共享的,哪些是不能被共享的,通過這種方式達到提高系統效率和減小記憶體消耗的目的。

從下圖看出,ConcreteFlyWeight就是可以共享的部分,通過工廠模式的方式來選擇共享的例項,客戶端就可以直接使用了。

我感覺就有點像簡單工廠模式,區別是不像工廠模式一樣每次都生成一個不同的物件例項,而是返回一個現成的物件例項。

暫時就只理解了這麼多,其他的需要在實踐中慢慢的總結。

image

常用場景

1.當系統中有大量的細粒度物件例項,而且這些物件例項中有一些屬性是重複的情況下,考慮使用。

文字編輯器,輸入法之類的常用應用。

優點

1.提高了系統的效率,減小了記憶體的消耗。

2.減少了重複程式碼。

3.減少了系統的複雜度。

缺點

1.維護共享物件和查詢所需的共享物件需要花費很多時間。

C++實現

複製程式碼
 1 #ifndef _FLYWEIGHT_H_
 2 #define _FLYWEIGHT_H_
 3 
 4 
 5 class FlyWeight
 6 {
 7 public:
 8     FlyWeight(){};
 9     virtual ~FlyWeight(){};
10 
11     virtual void operation() = 0;
12 
13 };
14 
15
16 class ConcreteFlyWeight: public FlyWeight 17 { 18 public: 19 ConcreteFlyWeight(){}; 20 ~ConcreteFlyWeight(){}; 21 22 void operation(); 23 24 }; 25 26 27 28 #endif
複製程式碼 複製程式碼
1 #include "FlyWeight.h"
2 #include <stdio.h>
3 
4 
5 void ConcreteFlyWeight::operation()
6 {
7     printf("I'm ConcreteFlyWeight!\n");
8 }
複製程式碼 複製程式碼
 1 #ifndef _FLYWEIGHT_FACTORY_H_
 2 #define _FLYWEIGHT_FACTORY_H_
 3 
 4 #include <vector>
 5 #include "FlyWeight.h"
 6 
 7 using namespace std;
 8 
 9 class FlyWeightFactory
10 {
11   public:
12     FlyWeightFactory();
13     ~FlyWeightFactory();
14 
15     FlyWeight* GetFlyWeight(int key);
16 
17   private:
18     vector<FlyWeight*> m_flyWeights;//很多時候為了增加效率,使用hash表之類的結構,這裡簡單的使用vector
19 };
20 
21 #endif
複製程式碼 複製程式碼
 1 #include "FlyWeightFactory.h"
 2 
 3 FlyWeightFactory::FlyWeightFactory()
 4 {
 5     FlyWeight* tmp = new ConcreteFlyWeight();
 6     m_flyWeights.push_back(tmp);
 7 }
 8 
 9 
10 
11 
12 FlyWeightFactory::~FlyWeightFactory()
13 {
14     FlyWeight* tmp = m_flyWeights.at(0);
15     delete tmp;
16     tmp = NULL;
17 }
18 
19 
20 
21 
22 FlyWeight* FlyWeightFactory::GetFlyWeight(int key)
23 {
24     //簡單點表示
25     return m_flyWeights.at(key);
26 }
複製程式碼 複製程式碼
 1 #include "FlyWeightFactory.h"
 2 
 3 
 4 
 5 int main()
 6 {
 7     FlyWeightFactory* factory = new FlyWeightFactory();
 8 
 9     FlyWeight* flyWeight = factory->GetFlyWeight(0);
10     flyWeight->operation();
11     return 0;
12 }
複製程式碼
g++ -o client client.cpp FlyWeight.cpp FlyWeightFactory.cpp

執行結果

image

轉自:http://www.cnblogs.com/cxjchen/p/3194379.html