說明:
物件之間,若有共同的部分可以共享,則將可共用的部分獨立為共享物件,
不能共享的部份外部化,使用時再將外部化的部分傳給共享物件。
這樣做的優點是減少記憶體使用量。缺點是程式邏輯可能變得較複雜。
範例:
黑白棋,在棋盤上放 3 顆黑棋, 3 顆白棋。一般情況,可能會實例化 6 顆獨立的棋子物件,每一個物件都有:黑棋或白棋、X作標、Y作標,三個資料。享元模式則是將共用的資料獨立為共用物件,下面範例,假設"黑棋"兩個字是黑棋共用的,"白棋"兩個字是白棋共用的,故規劃成共享物件;X、Y座標每個棋子都不一樣,所以獨立為外部資料,使用時再傳給共享物件。如此便可減少記憶體中的重覆資料。
希望達成如下的效果
static void Main(string[] args) { ChessFlyweightFactory f = new ChessFlyweightFactory(); ChessFlyweight a1 = f.GetChessFlyweight("黑棋"); // 取得黑棋共享物件 a1.Display(1, 1); // 提供座標資料(非共享資料) ChessFlyweight a2 = f.GetChessFlyweight("黑棋"); // 取得黑棋共享物件 a2.Display(1, 2); // 提供座標資料(非共享資料) ChessFlyweight a3 = f.GetChessFlyweight("黑棋"); // 取得黑棋共享物件 a3.Display(1, 3); // 提供座標資料(非共享資料) ChessFlyweight b1 = f.GetChessFlyweight("白棋"); // 取得白棋共享物件 b1.Display(2, 1); // 提供座標資料(非共享資料) ChessFlyweight b2 = f.GetChessFlyweight("白棋"); // 取得白棋共享物件 b1.Display(2, 2); // 提供座標資料(非共享資料) ChessFlyweight b3 = f.GetChessFlyweight("白棋"); // 取得白棋共享物件 b1.Display(2, 3); // 提供座標資料(非共享資料) Console.WriteLine("ChessFlyweight物件數量:{0}", f.GetChessFlyweightCount()); Console.Read(); }執行結果: (6顆棋,只有2個棋子物件)
黑棋(1,1) 黑棋(1,2) 黑棋(1,3) 白棋(2,1) 白棋(2,2) 白棋(2,3) ChessFlyweight物件數量:2
實現重點在於,區分共享資料和不可以共享的資料。共享資料做成共享物件,不可共享資料則使用時再傳給共享物件。實例化共享物件時,則由享元工廠把關,判斷目前始否已經實例化過該共享物件,若有則直接回傳現存的共享物件。
其餘程式碼
// 棋子享元工廠,回傳棋子物件 class ChessFlyweightFactory { private Hashtable chessFlyweight = new Hashtable(); public ChessFlyweight GetChessFlyweight(string key) { if (!chessFlyweight.ContainsKey(key)) { chessFlyweight.Add(key, new ConcreteChessFlyweight(key)); } return (ChessFlyweight)chessFlyweight[key]; } // 取得目前棋子物件數量 public int GetChessFlyweightCount() { return chessFlyweight.Count; } } // 棋子享元抽像物件 abstract class ChessFlyweight { protected string name; // 共享資料 public ChessFlyweight(string name) { this.name = name; } public abstract void Display(int x, int y); } // 棋子享元(共享物件) class ConcreteChessFlyweight : ChessFlyweight { public ConcreteChessFlyweight(string name) : base(name) { } // X、Y座標,非共享資料 public override void Display(int x, int y) { Console.WriteLine("{0}({1},{2})", this.name, x, y); } } /* // 不能共享的的享元(UnsharableFlyweight)(複合享元),一般應該用不到 class UnsharedConcreteChessFlyweight : ChessFlyweight { public UnsharedConcreteChessFlyweight(string name) : base(name) { } public override void Display(int x, int y) { Console.WriteLine("不共用的物件:{0}({1},{2})", this.name, x, y); } } */
相關連結:設計模式整理列表
沒有留言:
張貼留言