大話設計模式
1 享元模式(Flyweight)結構圖
2 對享元模式的一些解釋
概念:運用共享技術有效的支援大量細粒度的對象。【DP】
Flyweight類:是所有具體享元類的超類或接口,通過這個接口,Flyweight可以接受并作用于外部狀态。
class Flyweight
{
public:
virtual void Operatiron(int extrinsicstate) = 0;
};
ConcreteFlyweight類:繼承Flyweight類或實作Flyweight接口,并為内部狀态增加存儲空間。
class ConcreteFlyweight :public Flyweight
{
public:
void Operatiron(int extrinsicstate) override
{
cout << "具體Flyweight" << extrinsicstate << endl;
}
};
UnsharedFlyweight類,指那些不需要共享的Flyweight子類,因為Flyweight接口共享成為可能,但它并不強制共享。
class UnsharedFlyweight :public Flyweight
{
public:
void Operatiron(int extrinsicstate) override
{
cout << "不共享的具體Flyweight" << extrinsicstate << endl;
}
};
FlyweightFactory類:一個共享工廠,用來建立并管理Flyweight對象。它主要用來確定合理的共享Flyweight,當使用者請求一個Flyweight時, FlyweightFactory對象提供一個已建立的執行個體或者建立一個。(不一定非得這樣,完全可以在需要時判斷是否為空來決定是否執行個體化)
class FlyweightFactory
{
private:
Hashtable *flyweight = new Hashtable();
public:
FlyweightFactory()
{
flyweight.Add("X", new ConcreteFlyweight());//用法錯誤,這裡隻是表示出這種形式
flyweight.Add("Y", new ConcreteFlyweight());
flyweight.Add("Z", new ConcreteFlyweight());
}
Flyweight *GetFlyweight(string key)
{
return (Flyweight *)flyweight[key];
}
};
用戶端代碼:
int main()
{
int extrinsicstate = 22;
FlyweightFactory *f = new FlyweightFactory();
Flyweight *fx = f->GetFlyweight("X");
fx->Operatiron(--extrinsicstate);
Flyweight *fy = f->GetFlyweight("Y");
fx->Operatiron(--extrinsicstate);
Flyweight *fz = f->GetFlyweight("Z");
fx->Operatiron(--extrinsicstate);
Flyweight *uf = new UnsharedFlyweight();
uf->Operatiron(--extrinsicstate);
return 0;
}
優點: 享元模式可以避免大量非常相似類的開銷。在程式設計中,有時需要生成大量細粒度的類執行個體來表示資料。如果能發現這些執行個體除了幾個參數外基本上都是相同的,有時就能夠大幅度的減少需要執行個體化的類的數量。如果能把那些參數移到類執行個體的外面,在方法調用時将它們傳遞進來,就可以通過共享大幅度地減少單個執行個體的數目。
也就是說,享元模式Flyweight執行時所需的狀态是有内部的也可能有外部的,内部狀态存儲于ConcreteFlyweight對象之中,而外部對象則應該考慮由用戶端對象存儲或計算,當調用Flyweight對象的操作時,将該狀态傳遞給它。
應用場景:
- 如果一個應用程式使用了大量的對象,而大量的這些對象造成了很大的存儲開銷時就應該考慮使用;
- 對象的大多數狀态可以是外部狀态,如果删除對象的外部狀态(用戶端代碼),那麼可以用相對較少的共享對象取代很多組對象,此時可以考慮使用享元模式。
3 C++源代碼實作
3.1 源代碼結構圖
3.2 C++源代碼
User.h
#ifndef _USER_H_
#define _USER_H_
#include<string>
using std::string;
class User
{
private:
string name;
public:
User(string name)
{
this->name = name;
}
string getName()
{
return this->name;
}
};
#endif
Flyweight.h(Website類)
#ifndef _FLYWEIGHT_H_
#define _FLYWEIGHT_H_
#include"User.h"
#include<string>
using std::string;
class Flyweight
{
public:
virtual void Operation(User &user) = 0;
};
class ConcreteFlyweight:public Flyweight
{
private:
string name;
public:
ConcreteFlyweight(string name);
void Operation(User &user) override;
};
#endif
Flyweight.cpp(Website.cpp)
#include<iostream>
#include"Flyweight.h"
using std::cout;
using std::endl;
ConcreteFlyweight::ConcreteFlyweight(string name)
{
this->name = name;
}
void ConcreteFlyweight::Operation(User &user)
{
cout << "網站分類:\t" << name << ";\t使用者:" << user.getName() << endl;
}
FlyweightFactory.h(ConcreteWebsite.h)
#include<string>
#include<map>
using std::string;
using std::map;
#ifndef _FLYWEIGHT_FACTORY_H_
#define _FLYWEIGHT_FACTORY_H_
class Flyweight;
class FlyweightFactory
{
private:
map<string, Flyweight *> *mmap = new map<string, Flyweight *>();
public:
~FlyweightFactory();
Flyweight *GetGlyweightGategory(string key);
int GetFlywightCount();
};
#endif
FlyweightFactory.cpp(ConcreteFactory.cpp)
#include"Flyweight.h"
#include"FlyweightFactory.h"
FlyweightFactory::~FlyweightFactory()
{
for (auto &m : (*mmap))
{
delete m.second;
}
delete mmap;
}
Flyweight *FlyweightFactory::GetGlyweightGategory(string key)
{
for (const auto &m : (*mmap))
{
if (m.first == key)
return m.second;
}
(*mmap)[key] = new ConcreteFlyweight(key);
return (*mmap)[key];
}
int FlyweightFactory::GetFlywightCount()
{
return mmap->size();
}
用戶端Client.h
#include"Flyweight.h"
#include"FlyweightFactory.h"
#include<iostream>
using std::cout;
using std::endl;
int main()
{
FlyweightFactory *f = new FlyweightFactory();
Flyweight *fx1 = f->GetGlyweightGategory("産品展示");
fx1->Operation(User("小菜"));
Flyweight *fx2 = f->GetGlyweightGategory("産品展示");
fx2->Operation(User("大鳥"));
Flyweight *fx3 = f->GetGlyweightGategory("産品展示");
fx3->Operation(User("嬌嬌"));
Flyweight *fb1 = f->GetGlyweightGategory("部落格");
fb1->Operation(User("老頑童"));
Flyweight *fb2 = f->GetGlyweightGategory("部落格");
fb2->Operation(User("桃谷六仙"));
Flyweight *fb3 = f->GetGlyweightGategory("部落格");
fb3->Operation(User("南海鳄神"));
cout << "網站分類個數" << f->GetFlywightCount() << endl;
delete f;
system("pause");
return 0;
}
運作結果:
網站分類: 産品展示; 使用者:小菜
網站分類: 産品展示; 使用者:大鳥
網站分類: 産品展示; 使用者:嬌嬌
網站分類: 部落格; 使用者:老頑童
網站分類: 部落格; 使用者:桃谷六仙
網站分類: 部落格; 使用者:南海鳄神
網站分類個數2
請按任意鍵繼續. . .