天天看點

【設計模式】——享元模式基本了解:内部狀态與外部狀态享元模式應用

基本了解:

     享元模式(Flyweight):運用共享技術有效地支援大量細粒度的對象。來提供應用程式的性能,節省系統中重複建立對象執行個體的性能消耗。可以包含以下兩點含義:1、當我們系統中某個對象類型的執行個體較多的情況。2、并且要求這些執行個體進行分類後,發現真正有差別的分類很少的情況。享元模式的基本結構圖。

【設計模式】——享元模式基本了解:内部狀态與外部狀态享元模式應用

内部狀态與外部狀态

   在享元對象内部并且不會随環境改變而改變的共享部分,可以稱為享元對象的内部狀态,而随環境改變而改變的、不可共享的狀态就是外部狀态。享元模式可以避免大量非常相似類的開銷。享元模式Flyweight執行所需的狀态時有内部的也可能有外部的。内部狀态存儲于ConcreteFlyweight對象中,而外部對象則應該考慮有用戶端對象存儲或計算,當調用Flyweight對象的操作時,将該狀态傳遞給他。結合網站開發的例子。

//使用者,用于網站的客戶賬号,是網站類的外部狀态
    public class User
    {
        private string name;
        public User(string name)
        {
            this.name = name;
        }
        public string Name
        {
            get { return name; }
        }
    }
    //網站抽象類
    abstract class WebSite
    {
        public abstract void Use(User user);//使用 方法需要傳遞 使用者 對象
    }
    //具體網站類
    class ConcreteWebSite:WebSite
    {
        private string name = "";
        public ConcreteWebSite(string name)
        {
            this.name = name;
        }
        public override void Use(User user)  //實作use方法
        {
            Console.WriteLine("網站分類:" + name + "使用者:" + user.Name);
        }
    }
    //網站工廠類
    //網站工廠
    class WebSiteFactory
    {
        private Hashtable flyweights = new Hashtable();
        //獲得網站分類
        public WebSite GetWebSiteCategory(string key)  //判斷是否存在這個對象,如果存在,則直接傳回,若不存在,則執行個體化它再傳回
        {
            if (!flyweights.ContainsKey(key))
                flyweights.Add(key, new ConcreteWebSite(key));
            return ((WebSite)flyweights[key]);
        }
        //獲得網站分類總數
        public int GetWebSiteCount()  //得到執行個體的個數
        {
            return flyweights.Count;
        }
    }
           

  用戶端代碼:

static void Main(string[] args)
        {
            WebSiteFactory f = new WebSiteFactory();

            WebSite fx = f.GetWebSiteCategory("産品展示");  //執行個體化“産品展示”的“網站”對象
            fx.Use(new User("小菜"));

            WebSite fy = f.GetWebSiteCategory("産品展示");  //共享上方生成的對象,不再執行個體化
            fy.Use(new User("大鳥"));

            WebSite fz = f.GetWebSiteCategory("産品展示");
            fz.Use(new User("嬌嬌"));

            WebSite f1 = f.GetWebSiteCategory("部落格");
            f1.Use(new User("老頑童"));

            WebSite f2 = f.GetWebSiteCategory("部落格");
            f2.Use(new User("桃谷六仙"));

            WebSite f3 = f.GetWebSiteCategory("部落格");
            f3.Use(new User("南海鳄神"));

            Console.WriteLine("得到網站分類總數為{0}", f.GetWebSiteCount());  //統計執行個體化個數,結果輸出顯示

            Console.Read();

        }
           

享元模式應用

1、應用程式使用了大量的對象,而大量的這些對象造成了很大的存儲開銷是考慮使用。 2、對象的大多數狀态為外部狀态,删除這些狀态可以用相對較少的共享對象取代。

   因為用了享元模式,有了共享的對象,執行個體總數就大大減少了,如果共享的對象越多,存儲節約就越多,節約量随着共享狀态的增多而增大。