一、定義
享元模式:運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象。
解釋:需要大量重復(fù)new一個(gè)對(duì)象時(shí),使用享元模式可以讓你減少對(duì)象的初始化,從而減小內(nèi)存開銷。太蒼白了,理解的不到位,希望自己以后補(bǔ)充吧。
二、UML類圖及基本代碼

基本代碼:
public abstract class Flyweight { public abstract void Operation(int extrinsicstate); } public class ConcreteFlyweight : Flyweight { // 內(nèi)部狀態(tài) PRivate string intrinsicstate; // 構(gòu)造函數(shù) public ConcreteFlyweight(string innerState) { this.intrinsicstate = innerState; } /// <summary> /// 享元類的實(shí)例方法 /// </summary> /// <param name="extrinsicstate">外部狀態(tài)</param> public override void Operation(int extrinsicstate) { Console.WriteLine("具體實(shí)現(xiàn)類: intrinsicstate {0}, extrinsicstate {1}", intrinsicstate, extrinsicstate); } }public class FlyweightFactory { // 最好使用泛型Dictionary<string,Flyweighy> //public Dictionary<string, Flyweight> flyweights = new Dictionary<string, Flyweight>(); public Hashtable flyweights = new Hashtable(); public FlyweightFactory() { flyweights.Add("A", new ConcreteFlyweight("A")); flyweights.Add("B", new ConcreteFlyweight("B")); flyweights.Add("C", new ConcreteFlyweight("C")); } public Flyweight GetFlyweight(string key) { // 更好的實(shí)現(xiàn)如下 //Flyweight flyweight = flyweights[key] as Flyweight; //if (flyweight == null) //{ // Console.WriteLine("駐留池中不存在字符串" + key); // flyweight = new ConcreteFlyweight(key); //} //return flyweight; return flyweights[key] as Flyweight; } }
客戶端調(diào)用:

class Program { static void Main(string[] args) { // 定義外部狀態(tài),例如字母的位置等信息 int externalstate = 10; // 初始化享元工廠 FlyweightFactory factory = new FlyweightFactory(); // 判斷是否已經(jīng)創(chuàng)建了字母A,如果已經(jīng)創(chuàng)建就直接使用創(chuàng)建的對(duì)象A Flyweight fa = factory.GetFlyweight("A"); if (fa != null) { // 把外部狀態(tài)作為享元對(duì)象的方法調(diào)用參數(shù) fa.Operation(--externalstate); } // 判斷是否已經(jīng)創(chuàng)建了字母B Flyweight fb = factory.GetFlyweight("B"); if (fb != null) { fb.Operation(--externalstate); } // 判斷是否已經(jīng)創(chuàng)建了字母D Flyweight fd = factory.GetFlyweight("D"); if (fd != null) { fd.Operation(--externalstate); } else { Console.WriteLine("駐留池中不存在字符串D"); // 這時(shí)候就需要?jiǎng)?chuàng)建一個(gè)對(duì)象并放入駐留池中 ConcreteFlyweight d = new ConcreteFlyweight("D"); factory.flyweights.Add("D", d); } Console.Read(); } }
運(yùn)行結(jié)果:

三、具體實(shí)例:
構(gòu)建一個(gè)由不同用戶使用的通用網(wǎng)站,具體代碼如下:
public class User { private string name; public string Name { get { return name; } } public User(string name) { this.name = 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) { Console.WriteLine("website type:" + name + "user:" + 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; } }
客戶端調(diào)用:

WebsiteFactory wf = new WebsiteFactory(); Website wx = wf.GetWebsiteCategory("show"); wx.Use(new User("a")); Website wy = wf.GetWebsiteCategory("show"); wy.Use(new User("b")); Website wz = wf.GetWebsiteCategory("see"); wz.Use(new User("c")); Console.WriteLine("website type num:" + wf.GetWebsiteCount());
四、優(yōu)缺點(diǎn)及適用場(chǎng)景
優(yōu)點(diǎn):
降低了系統(tǒng)中對(duì)象的數(shù)量,從而降低了系統(tǒng)中細(xì)粒度對(duì)象給內(nèi)存帶來(lái)的壓力。
缺點(diǎn):
1)為了使對(duì)象可以共享,需要將對(duì)象的一些狀態(tài)外部化,增加了系統(tǒng)復(fù)雜度
2)將享元對(duì)象狀態(tài)外部化,使得讀取外部狀態(tài)的運(yùn)行時(shí)間稍微變長(zhǎng)。
適用場(chǎng)景:
系統(tǒng)中需要大量的細(xì)粒度對(duì)象,同時(shí)這些對(duì)象耗費(fèi)大量的內(nèi)存,并且對(duì)象的狀態(tài)大部分可以外部化,此時(shí)使用享元模式是沒有錯(cuò)的。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注