文章出處
文章列表
在今天,讀書有時是件“麻煩”事。它需要你付出時間,付出精力,還要付出一份心境。--僅以《大話設計模式》來祭奠那逝去的……
享元模式:運用共享技術有效地支持大量細粒度的對象,避免大量的相似對象的開銷
程序設計中,有時需要大量細粒度的對象。如果能從這些對象中發現除了幾個參數不同其他都是相同的話,可以通過將這些相同參數移到實例外,構建享元類,在方法調用時將具體對象傳進來,來減少享元類被實例化的數目,減少系統消耗
1.網頁游戲刷屏怪物
千萬怪物靈魂,來到輪回工廠。工廠將靈魂放入生產線,賦予種族模板和皮膚模板(假設一款游戲,有3種怪物,每一種怪物樣子都一樣,boss和小怪只有皮膚顏色不同。如果怪物的屬性是名字、樣子和皮膚顏色,那么我們實例化一只怪物的時候,同時需要實例化一次樣子和皮膚。數量少的話,還無所謂,一旦要實例化10W、100W只怪物的話,我們就需要實例化10W、100W次樣子和皮膚,系統承擔很大的內存消耗。通過觀察,怪物的樣子數量是固定的,皮膚顏色也是固定的,我們可以將這兩個屬性共享出去,這樣實例化怪物的時候,就減少了樣子和皮膚的實例化對象數量)
定義享元類的超類或者接口,可以接受或者作用于外部狀態
/// <summary> /// 具體享元類的超類或者接口(可以接受或者作用于外部狀態) /// </summary> public abstract class Flyweight { /// <summary> /// 顏色(內部狀態) /// </summary> public string Colour { get; set; } /// <summary> /// 種類(內部狀態) /// </summary> public string Kind { get; set; } /// <summary> /// 操作flyweight使用者 /// </summary> /// <param name="name">flyweight使用者(外部狀態)</param> public abstract void Operation(string obj); }
定義怪物模型,具體的享元類,為內部狀態增加存儲空間
/// <summary> /// 怪物模型類(具體享元類,為內部狀態增加存儲空間) /// </summary> public class MonsterModel : Flyweight { /// <summary> /// 給怪物靈魂賦予種族和皮膚 /// </summary> /// <param name="obj">怪物靈魂</param> public override void Operation(string obj) { Console.WriteLine("{0},系統大神賦予了我{1}種族的樣子和{2}的皮膚,哇咔咔~我來了,菜鳥們~", obj, this.Kind, this.Colour); } }
定義享元工廠,用來創建和管理享元對象。確保合理的共享享元對象,當用戶請求一個享元對象時,工廠提供一個已創建的或者創建一個(如果不存在的話),這里可以同單例模式一起使用
/// <summary> /// 享元工廠(用來創建和管理享元對象。確保合理的共享享元對象,當用戶請求一個享元對象時,工廠提供一個已創建的實例或創建一個(如果不存在的話)) /// </summary> public class FlyweightFactory { public Hashtable flyweights = new Hashtable(); public FlyweightFactory() { flyweights.Add("白色史萊姆", new MonsterModel() { Kind = "史萊姆", Colour = "白色" }); flyweights.Add("藍色史萊姆", new MonsterModel() { Kind = "史萊姆", Colour = "藍色" }); flyweights.Add("紫色史萊姆", new MonsterModel() { Kind = "史萊姆", Colour = "紫色" }); } public Flyweight GetFlyweight(string key) { return (Flyweight)flyweights[key]; } }
開啟場景模擬
static void Main(string[] args) { //千萬怪物靈魂 string model = "我是萬千怪物靈魂中的{0}號"; //來到輪回工廠 FlyweightFactory factory = new FlyweightFactory(); //工廠將靈魂放入生產線 for (int n = 0; n < 10; n++) { //賦予種族模板和皮膚模板 factory.GetFlyweight("白色史萊姆").Operation(string.Format(model, n)); } }
文章列表
全站熱搜