1. 程式人生 > >【設計模式】——享元模式

【設計模式】——享元模式

【享元模式】

 

享元模式(Flyweight):運用共享技術有效地支援大量細粒度的物件,減少建立物件的數量以減少記憶體的佔用和提高效能,提供了減少物件數量從而改善應用所需要的物件結構的方式

 

【介紹】

 

  • 如何解決:用唯一標識碼判斷,如果在記憶體中又,則返回這個唯一標識碼所標識的物件

  • 關鍵程式碼:用MashMap儲存這些物件

  • 優點:大大減少了物件的建立,降低系統的記憶體,提高效率

  • 缺點:提高了系統的複雜度,需要分離出外部狀態和內部狀態,而且外部狀態具有固有化的性質,不隨著內部狀態的變化而變化,否則則會造成系統的混亂

  • 注意事項:注意劃分外部狀態和內部狀態,否則會氫氣執行緒安全問題;這些類必須有一個工廠物件加以控制

 

 

【實現】

 

 

 

 

步驟一:外部狀態物件:使用者


 

public class  User

    {

        private string name;

        public User(string name)

        {

            this.name = name;

        }

        public string Name

        {

            get { return name; }

        }

    }

步驟二:flayweight類:網站類


 

 abstract class WebSite

    {

        public abstract void Use(User user);//方法需要傳遞使用者物件

    }

 

步驟三:concreteFlyweight類:具體網站類


 

 class ConcreteWebSit:WebSite

    {

        private string name = "";

        public ConcreteWebSit (string name)

        {

            this.name = name;

        }

        public override void Use(User user)

        {

            Console.WriteLine("網站分類:"+name+"    使用者:"+user .Name );

        }

    }

步驟四:flyweightfactory類:網站工廠類


 

class WebSiteFactory

    {

        private Hashtable flyweights = new Hashtable();

        //獲得網站分類

        public WebSite GetWebSiteCategory(string key)

        {

            if (!flyweights.ContainsKey(key))

                flyweights.Add(key, new ConcreteWebSit(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("皮皮華"));

            Console.WriteLine("");



            WebSite fx1 = f.GetWebSiteCategory("產品展示");

            fx1.Use(new User("皮皮傑"));

            Console.WriteLine("");

            WebSite fx2 = f.GetWebSiteCategory("產品展示");

            fx2.Use(new User("皮皮軍"));

            Console.WriteLine("");



            WebSite f1= f.GetWebSiteCategory("部落格");

            f1.Use(new User("皮皮鬼"));

            Console.WriteLine("");



            WebSite f2 = f.GetWebSiteCategory("部落格");

            f2.Use(new User("皮皮人"));

            Console.WriteLine("");



            WebSite f3= f.GetWebSiteCategory("部落格");

            f3.Use(new User("皮皮神"));

            Console.WriteLine("");



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

            Console.Read();

        }

    }

 

步驟五:執行結果

網站分類:產品展示    使用者:皮皮華



網站分類:產品展示    使用者:皮皮傑



網站分類:產品展示    使用者:皮皮軍



網站分類:部落格    使用者:皮皮鬼



網站分類:部落格    使用者:皮皮人



網站分類:部落格    使用者:皮皮神



得到網站總數為:2

 

 

 

【總結】

 

一、在享元物件內部並且不會隨著環境改變而改變的共享部分,稱為是享元物件的內部狀態,隨著環境的改變而改變的,不可以共享的狀態就是外部狀態

二、享元模式可以避免大量非常相似類的開銷。

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