C#設計模式之享元模式

提高班14期郭倩_Ulrica發表於2018-06-08

前言

享元不是很好理解,但是它的另外一個解釋__共享,就很好理解了。一起來看看吧

享元模式

英文:Flyweight
運用共享技術有效的支援大量細粒度的物件

情景

拿書上的例子來說,如果100家企業來找你做網站,難道要去申請100個空間,用100個資料庫來貼上100遍同樣的程式碼嗎?肯定不可以,網站增多,例項也隨著增多,這對伺服器的資源浪費的很嚴重。
如果大家的網站共享一套程式碼,只要使用者ID不同,可以區分不同的客戶,具體資料和模板也可以不同,但程式碼核心和資料庫卻可以是共享的,那不僅是減少了伺服器資源的浪費,也很容易去維護和擴充套件了。

這裡寫圖片描述

應用

如果一個應用程式使用了大量的物件,而大量這些物件造成了很大的儲存開銷時就應該考慮使用;還有就是物件的大多數狀態可以外部狀態,如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件,此時可以考慮使用享元模式。

內部狀態與外部狀態

在享元物件內部並且不會隨環境改變而改變的共享部分,可以稱為是享元物件的內部狀態,而隨環境改變而改變的,不可以共享的狀態就是外部狀態了。
享元模式可以避免大量非常相似類的開銷。
內部狀態儲存於concreteflyweight中,而外部物件則應該考慮由客戶端物件儲存或計算。當呼叫享元物件的操作時,將該狀態傳遞給它。
下面例子中的客戶賬號就是外部狀態,應該由專門的物件來處理。

程式碼展示

使用者類:(網站的外部狀態)

//使用者類,是網站類的外部狀態
    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;
        }
    }

客戶端程式碼:

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

            WebSite fx = f.GetWebSiteCategory("產品展示");
            fx.Use(new User("小貓"));

            WebSite fz = f.GetWebSiteCategory("產品展示");
            fz.Use(new User("小狗"));

            WebSite fw = f.GetWebSiteCategory("部落格");
            fw.Use(new User("小鴨子"));

            WebSite fq = f.GetWebSiteCategory("部落格");
            fq.Use(new User("小企鵝"));

            WebSite fu = f.GetWebSiteCategory("吃貨");
            fu.Use(new User("小猴子"));

            WebSite fo = f.GetWebSiteCategory("吃貨");
            fo.Use(new User("小天使"));

            Console.WriteLine("得到網站分類總數為{0}",f.GetWebSiteCount ());

            Console.Read();
        }
    }

後記

記錄每一次成長~

相關文章