元对象我所理解的设计模式(C++实现)——享元模式(Flyweight Pattern)
這段時(shí)間個(gè)人幾篇文章介紹了改元對(duì)象的文章. 關(guān)聯(lián)文章的地址
????
概述
????想想我們編輯文檔用的wps,文檔里文字很多都是重復(fù)的,我們弗成能為每個(gè)涌現(xiàn)的漢字都創(chuàng)建獨(dú)立的空間,這樣代價(jià)太大,最好的方法就是同享其中雷同的部分,使得需要?jiǎng)?chuàng)建的對(duì)象降到最小,這個(gè)就是享元模式的核心,即運(yùn)用同享技巧有效地支持大批細(xì)粒度的對(duì)象。
????享元對(duì)象能做到同享的關(guān)鍵是辨別內(nèi)蘊(yùn)狀態(tài)(Internal?State)和外蘊(yùn)狀態(tài)(External?State)。內(nèi)蘊(yùn)狀態(tài)是存儲(chǔ)在享元對(duì)象外部并且不會(huì)隨環(huán)境改變而改變。因此內(nèi)蘊(yùn)狀態(tài)并可以同享。
????外蘊(yùn)狀態(tài)是隨環(huán)境改變而改變的、弗成以同享的狀態(tài)。享元對(duì)象的外蘊(yùn)狀態(tài)必須由客戶端保存,并在享元對(duì)象被創(chuàng)建之后,在需要使用的時(shí)候再傳入到享元對(duì)象外部。外蘊(yùn)狀態(tài)與內(nèi)蘊(yùn)狀態(tài)是相互獨(dú)立的。
????
類圖與樣例
????
????抽象享元類(Flyweight)
????它是全部詳細(xì)享元類的超類。為這些類規(guī)定出需要實(shí)現(xiàn)的大眾接口,那些需要外蘊(yùn)狀態(tài)(Exte的操縱可以通過方法的參數(shù)傳入。抽象享元的接口使得享元變得可能,但是其實(shí)不強(qiáng)制子類實(shí)行同享,因此并非全部的享元對(duì)象都是可以同享的。
????詳細(xì)享元類(ConcreteFlyweight)
????詳細(xì)享元類實(shí)現(xiàn)了抽象享元類所規(guī)定的接口。如果有內(nèi)蘊(yùn)狀態(tài)的話,必須擔(dān)任為內(nèi)蘊(yùn)狀態(tài)提供存儲(chǔ)空間。享元對(duì)象的內(nèi)蘊(yùn)狀態(tài)必須與對(duì)象所處的周圍環(huán)境無關(guān),從而使得享元對(duì)象可以在系統(tǒng)內(nèi)同享。有時(shí)候詳細(xì)享元類又稱為單純?cè)敿?xì)享元類,因?yàn)閺?fù)合享元類是由單純?cè)敿?xì)享元角色通過復(fù)合而成的。
????不能同享的詳細(xì)享元類(UnsharableFlyweight)
????不能同享的享元類,又叫做復(fù)合享元類。一個(gè)復(fù)合享元對(duì)象是由多個(gè)單享元對(duì)象構(gòu)成,這些構(gòu)成的對(duì)象是可以同享的,但是復(fù)合享元類本身其實(shí)不能同享。
????享元工廠類(FlyweightFactoiy)
????享元工廠類擔(dān)任創(chuàng)建和管理享元對(duì)象。當(dāng)一個(gè)客戶端對(duì)象請(qǐng)求一個(gè)享元對(duì)象的時(shí)候,享元工廠需要檢查系統(tǒng)中是不是已經(jīng)有一個(gè)符合要求的享元對(duì)象,如果已經(jīng)有了,享元工廠角色就應(yīng)當(dāng)提供這個(gè)已有的享元對(duì)象;如果系統(tǒng)中沒有恰當(dāng)?shù)南碓獙?duì)象的話,享元工廠角色就應(yīng)當(dāng)創(chuàng)建一個(gè)新的適合的享元對(duì)象。
????客戶類(Client)
????客戶類需要自行存儲(chǔ)全部享元對(duì)象的外蘊(yùn)狀態(tài)。
????
每日一道理風(fēng),那么輕柔,帶動(dòng)著小樹、小草一起翩翩起舞,當(dāng)一陣清風(fēng)飄來,如同母親的手輕輕撫摸自己的臉龐,我喜歡那種感覺,帶有絲絲涼意,讓人心曠神怡。享受生活,不一定要有山珍海味、菱羅綢緞為伴,大自然便是上帝所賜予人類最為珍貴的。
// CplusplusFlyweight.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include <iostream> #include <map> using namespace std; class Character { public:virtual ~Character(){};virtual void SetSize(int, int) = 0;virtual void Display() = 0; protected:Character(){};char m_chSymbol;int m_nWeight;int m_nHeight; };class CharacterA : public Character { public:CharacterA();virtual ~CharacterA();void SetSize(int, int);void Display(); };CharacterA::CharacterA() {this->m_chSymbol = 'A';this->m_nWeight = 100;this->m_nHeight = 200; }CharacterA::~CharacterA() {} void CharacterA::SetSize(int nWeight, int nHeight) {this->m_nWeight = nWeight;this->m_nHeight = nHeight; } void CharacterA::Display() {cout << "CharacterA:" << m_chSymbol << "(" << m_nWeight << "," << m_nHeight << ")" << endl; }class CharacterB : public Character { public:CharacterB();virtual ~CharacterB();void SetSize(int, int);void Display(); };CharacterB::CharacterB() {this->m_chSymbol = 'B';this->m_nWeight = 100;this->m_nHeight = 200; }CharacterB::~CharacterB() {}void CharacterB::SetSize(int nWeight, int nHeight) {this->m_nWeight = nWeight;this->m_nHeight = nHeight; }void CharacterB::Display() {cout << "CharacterB:" << m_chSymbol << "(" << m_nWeight << "," << m_nHeight << ")" << endl; }class CharacterFactory { public:CharacterFactory();virtual ~CharacterFactory();Character* GetCharacter(char); private:std::map<char, Character*> m_mChar; };CharacterFactory::CharacterFactory() {m_mChar.insert(make_pair<char, Character*>('A', new CharacterA));m_mChar.insert(make_pair<char, Character*>('B', new CharacterB)); }CharacterFactory::~CharacterFactory() {}Character* CharacterFactory::GetCharacter(char chIn) {map<char, Character*>::iterator it = m_mChar.find(chIn);if(it != m_mChar.end()){return (Character*)it->second;}return NULL; }int _tmain(int argc, _TCHAR* argv[]) {CharacterFactory* pFactory = new CharacterFactory;//內(nèi)蘊(yùn)狀態(tài) 存儲(chǔ)在享元對(duì)象外部并且不會(huì)隨環(huán)境改變而改變Character* ch1 = pFactory->GetCharacter('A');ch1->Display();//外蘊(yùn)狀態(tài) 客戶端保存Character* ch2 = pFactory->GetCharacter('B');ch2->SetSize(500, 800);ch2->Display();return 0; }
????
要點(diǎn)
????1、面向?qū)ο蠛芎玫奶幚砹顺橄笮缘膯栴},但是作為一個(gè)運(yùn)行在呆板中的程序?qū)嶓w,我們需要斟酌對(duì)象的代價(jià)問題。Flyweight設(shè)計(jì)模式重要處理面向?qū)ο蟮拇鷥r(jià)問題,一般不觸及面向?qū)ο蟮某橄笮詥栴}。
????2、Flyweight采用對(duì)象同享的做法來下降系統(tǒng)中對(duì)象的個(gè)數(shù),從而下降細(xì)粒度對(duì)象給系統(tǒng)帶來的內(nèi)存壓力。在詳細(xì)實(shí)現(xiàn)方面,要注意對(duì)象狀態(tài)的處理。
????3、享元模式的長(zhǎng)處在于它大幅度地下降內(nèi)存中對(duì)象的數(shù)量。但是,它做到這一點(diǎn)所付出的代價(jià)也是很高的:享元模式使得系統(tǒng)更加復(fù)雜。為了使對(duì)象可以同享,需要將一些狀態(tài)外部化,這使得程序的邏輯復(fù)雜化。另外它將享元對(duì)象的狀態(tài)外部化,而讀取外部狀態(tài)使得運(yùn)行時(shí)間稍微變長(zhǎng)。
????
適用性
????當(dāng)以下全部的條件都滿足時(shí),可以斟酌使用享元模式:
????1、一個(gè)系統(tǒng)有大批的對(duì)象。?
????2、這些對(duì)象耗費(fèi)大批的內(nèi)存。?
????3、這些對(duì)象的狀態(tài)中的大部分都可以外部化。?
????4、這些對(duì)象可以按照內(nèi)蘊(yùn)狀態(tài)分紅很多的組,當(dāng)把外蘊(yùn)對(duì)象從對(duì)象中剔除時(shí),每個(gè)組都可以僅用一個(gè)對(duì)象代替。?
????5、軟件系統(tǒng)不依賴于這些對(duì)象的身份,換言之,這些對(duì)象可以是弗成分辨的。
????滿足以上的這些條件的系統(tǒng)可以使用享元對(duì)象。最后,使用享元模式需要維護(hù)一個(gè)記錄了系統(tǒng)已有的全部享元的表,而這需要耗費(fèi)資源。因此,應(yīng)當(dāng)在有足夠多的享元實(shí)例可供同享時(shí)才值得使用享元模式。
????
優(yōu)缺點(diǎn)
????享元模式的長(zhǎng)處在于它大幅度地下降內(nèi)存中對(duì)象的數(shù)量。但是,它做到這一點(diǎn)所付出的代價(jià)也是很高的:
????1、享元模式使得系統(tǒng)更加復(fù)雜。為了使對(duì)象可以同享,需要將一些狀態(tài)外部化,這使得程序的邏輯復(fù)雜化。
????2、享元模式將享元對(duì)象的狀態(tài)外部化,而讀取外部狀態(tài)使得運(yùn)行時(shí)間稍微變長(zhǎng)。
????
????LCL_data原創(chuàng)于CSDN.NET【http://blog.csdn.net/lcl_data/article/details/8974679】
文章結(jié)束給大家分享下程序員的一些笑話語(yǔ)錄: IBM和波音777
波音777是有史以來第一架完全在電腦虛擬現(xiàn)實(shí)中設(shè)計(jì)制造的飛機(jī),所用的設(shè)備完全由IBM公司所提供。試飛前,波音公司的總裁非常熱情的邀請(qǐng)IBM的技術(shù)主管去參加試飛,可那位主管卻說道:“啊,非常榮幸,可惜那天是我妻子的生日,So..”..
波音公司的總載一聽就生氣了:“膽小鬼,我還沒告訴你試飛的日期呢!”
--------------------------------- 原創(chuàng)文章 By
元和對(duì)象
---------------------------------
轉(zhuǎn)載于:https://www.cnblogs.com/jiangu66/archive/2013/05/26/3100664.html
總結(jié)
以上是生活随笔為你收集整理的元对象我所理解的设计模式(C++实现)——享元模式(Flyweight Pattern)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二叉树节点数据结构-练习 5 二叉树的建
- 下一篇: u盘 坏了怎么办 U盘损坏了,怎么办?