享元模式運用共享技術有效支援大量細粒度物件。核心概念區分:
將外部狀態移出物件,透過共享極少數內部狀態物件,大幅減少實例數量。
GetFlyweight(key),若存在則回傳既有實例Operation(extrinsicState)
// FlyweightFactory
public class FlyweightFactory {
Hashtable flyweights = new Hashtable();
public FlyweightFactory() {
flyweights.Add("A", new ConcreteFlyweight());
flyweights.Add("B", new ConcreteFlyweight());
flyweights.Add("C", new ConcreteFlyweight());
}
public Flyweight GetFlyweight(string key) => flyweights[key] as Flyweight;
}
// Flyweight 抽象與實作
public abstract class Flyweight { public abstract void Operation(int extrinsicState); }
public class ConcreteFlyweight : Flyweight {
public override void Operation(int s) => Console.WriteLine($"{GetType().Name}:{s}");
}
public class UnsharedConcreteFlyweight : Flyweight {
public override void Operation(int s) => Console.WriteLine($"{GetType().Name}:{s}");
}
// Client
static void Main() {
int state = 20;
var factory = new FlyweightFactory();
factory.GetFlyweight("A").Operation(--state);
factory.GetFlyweight("B").Operation(--state);
factory.GetFlyweight("C").Operation(--state);
new UnsharedConcreteFlyweight().Operation(--state);
}
文件 Document 中大量字元重複,僅字型大小(外部狀態)不同。結構:
CharacterFactory:以 Dictionary<char, Character> 快取,GetCharacter 採延遲初始化Character 抽象類別:內部狀態含 symbol、width、height、ascent、descent、pointSizeCharacterA~CharacterZ:各字元具體類別,Display(pointSize) 顯示
// CharacterFactory 關鍵片段
public Character GetCharacter(char key) {
if (_characters.ContainsKey(key)) return _characters[key];
Character c = key switch { 'A' => new CharacterA(), 'B' => new CharacterB(), /*...*/ 'Z' => new CharacterZ() };
_characters.Add(key, c);
return c;
}
// Client
string doc = "AAZZBBZB";
var factory = new CharacterFactory();
int pt = 10;
foreach (char c in doc) {
factory.GetCharacter(c).Display(++pt);
}
享元模式透過內外部狀態分離與工廠快取,極大降低大量相似物件的記憶體佔用,適用於字元、圖示、棋子等大量重複細粒度物件場景。