設計模式之享元(FlyWeight)---對象結構型模式

                     設計模式之享元(FlyWeight)---對象結構型模式



1.意圖

運用共享技術有效地支持大量細粒度的對象。

2.適用性

1)一個應用程序使用了大量的對象。
2)完全由於使用大量的對象,造成很大的存儲開銷。
3)對象的大多數狀態都可變爲外部狀態。
4)如果刪除對象的外部狀態,那麼可以用相對較少的共享對象取代很多組對象。
5)應用程序不依賴於對象標識。由於 FlyWeight 對象可以被共享,對於概念上明顯有別的對象,標識測試將返回真值。

3.結構

1)結構圖如圖(F1)





2)下面的對象圖說明了如何共享Flyweight。



4.參與者

*Flyweight
---描述一個接口,通過這個接口Flyweight可以接受並作用於外部狀態。
*ConcreteFlyweight
---實現Flyweight接口,併爲內部狀態增加存儲空間。ConcreteFlyweight對象必須是可共享的。它所存儲的狀態必須是內部的;即:他必須獨立於ConcreteFlyweight對象的場景。
*UnsharedConcreteFlyweight
---並非所有的Flyweight子類都需要被共享,Flyweight接口使共享成爲可能,但他並不強制共享。在Flyweight對象結構的某些層次,UnsharedConcreteFlyweight對象通常將ConcreteFlyweight對象作爲子節點。
*FlyweightFactory
---創建並管理flyweight對象。
---確保合理的共享flyweight。當用戶請求一個Flyweight時。FlyweightFactory對象提供一個已 創建的實例或者創建一個。
*Client
---維持一個對Flyweight的引用。
---計算或存儲一個(多個) Flyweight的外部狀態。


5.協作

1)flyweight執行時所需的狀態必定是內部的或外部的。內部狀態存儲於 ConcreteFlyweight對象之中;外部對象則有Client 對象存儲或計算。當對象那個調用flyweight對象操作時,將該狀態傳遞給他。
2)用戶不直接對ConcreteFlyweight類進行實例化,而只能從FlyweightFactory對象得到ConcreteFlyweight對象,這可保證對他們適當的共享。

6.代碼示例:

/*********************************************************
*
*
*
* 下面的例子是一個文檔編輯器的例子,對字符(Charact)實現共享,* 有利於節省空間存儲.
*
* 對應關係:Flyweight---Glyph
* ConcreteFlyweight---Charact
* UnsharedConcreteFlyweight---Row,Column
* FlyweightFactory----GlyphFactory
*
*
*
***************************************************************/


class Window;
class GlyphContext;
class Font {
public:
Font(char*);
};
class BTree;

class Glyph {
public:
virtual ~Glyph();

virtual void Draw(Window*, GlyphContext&);

virtual void SetFont(Font*, GlyphContext&);
virtual Font* GetFont(GlyphContext&);

virtual void First(GlyphContext&);
virtual void Next(GlyphContext&);
virtual bool IsDone(GlyphContext&);
virtual Glyph* Current(GlyphContext&);

virtual void Insert(Glyph*, GlyphContext&);
virtual void Remove(GlyphContext&);
protected:
Glyph();
};

class Character : public Glyph {
public:
Character(char);

virtual void Draw(Window*, GlyphContext&);
private:
char _charcode;
};

class GlyphContext {
public:
GlyphContext();
virtual ~GlyphContext();

virtual void Next(int step = 1);
virtual void Insert(int quantity = 1);

virtual Font* GetFont();
virtual void SetFont(Font*, int span = 1);
private:
int _index;
BTree* _fonts;
};

void dummy () {

GlyphContext gc;
Font* times12 = new Font("Times-Roman-12");
Font* timesItalic12 = new Font("Times-Italic-12");
// ...

gc.SetFont(times12, 6);

gc.Insert(6);
gc.SetFont(timesItalic12, 6);

}

class Row {
};
class Column {
};

const int NCHARCODES = 128;

class GlyphFactory {
public:
GlyphFactory();
virtual ~GlyphFactory();

virtual Character* CreateCharacter(char);
virtual Row* CreateRow();
virtual Column* CreateColumn();
// ...
private:
Character* _character[NCHARCODES];
};

GlyphFactory::GlyphFactory () {
for (int i = 0; i < NCHARCODES; ++i) {
_character[i] = 0;
}
}


Character* GlyphFactory::CreateCharacter (char c) {
if (!_character[c]) {
_character[c] = new Character(c);
}

return _character[c];
}

Row* GlyphFactory::CreateRow () {
return new Row;
}


Column* GlyphFactory::CreateColumn () {
return new Column;
}


//附: 想起來挺簡單的,可這個模式要實現真不會.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章