文章出處

在今天,讀書有時是件“麻煩”事。它需要你付出時間,付出精力,還要付出一份心境。--僅以《大話設計模式》來祭奠那逝去的……

享元模式:運用共享技術有效地支持大量細粒度的對象,避免大量的相似對象的開銷

程序設計中,有時需要大量細粒度的對象。如果能從這些對象中發現除了幾個參數不同其他都是相同的話,可以通過將這些相同參數移到實例外,構建享元類,在方法調用時將具體對象傳進來,來減少享元類被實例化的數目,減少系統消耗

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));
            }
        }

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()