国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

講解C#設(shè)計模式編程中享元模式的運用

2020-01-24 01:15:53
字體:
供稿:網(wǎng)友

一、概述

在軟件開發(fā)中,我們有時需要創(chuàng)建大量細粒度的對象,比如文檔處理系統(tǒng)就可能需要創(chuàng)建成千上萬的字符對象。但如果對每個字符對象都分配內(nèi)存,那么在系統(tǒng)運行時就會耗費大量的內(nèi)存。如何在保留面向?qū)ο蟛僮鞣绞絻?yōu)點的同時避免創(chuàng)建大量的對象呢?這就到了享元模式發(fā)揮作用的時候了。

二、享元模式

享元模式運用共享技術(shù)有效地支持大量細粒度的對象。例如可以對文檔處理系統(tǒng)創(chuàng)建共享池,在共享池中建立字母和代碼的對應(yīng)關(guān)系,這樣就可以用共享池中的26個對象解決需要創(chuàng)建大量對象的問題。其結(jié)構(gòu)圖如下:

201622291612761.jpg (467×289)

Flyweight定義了享元接口,外部對象通過這個接口來訪問具體的享元對象。

ConcreteFlyweight實現(xiàn)Flyweight接口,定義了具體的享元對象,并保存享元對象的內(nèi)部狀態(tài)。該享元對象是可共享的。

UnsharedConcreteFlyweight實現(xiàn)Flyweight接口,定義了不用于共享的享元對象。

FlyweightFactory創(chuàng)建并管理享元對象。

Client保存對享元接口的引用,通過該引用有效的使用具體的享元對象。

三、示例
下面以一個實際的應(yīng)用來實現(xiàn)下享元模式。這個例子是:一個文本編輯器中會出現(xiàn)很多字面,使用享元模式去實現(xiàn)這個文本編輯器的話,會把每個字面做成一個享元對象。享元對象的內(nèi)部狀態(tài)就是這個字面,而字母在文本中的位置和字體風(fēng)格等其他信息就是它的外部狀態(tài)。下面就以這個例子來實現(xiàn)下享元模式,具體實現(xiàn)代碼如下:

/// <summary> /// 客戶端調(diào)用 /// </summary> class Client {  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)建的對象A   Flyweight fa = factory.GetFlyweight("A");   if (fa != null)   {    // 把外部狀態(tài)作為享元對象的方法調(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)建了字母C   Flyweight fc = factory.GetFlyweight("C");   if (fc != null)   {    fc.Operation(--externalstate);   }   // 判斷是否已經(jīng)創(chuàng)建了字母D   Flyweight fd= factory.GetFlyweight("D");   if (fd != null)   {    fd.Operation(--externalstate);   }   else   {    Console.WriteLine("駐留池中不存在字符串D");    // 這時候就需要創(chuàng)建一個對象并放入駐留池中    ConcreteFlyweight d = new ConcreteFlyweight("D");    factory.flyweights.Add("D", d);   }   Console.Read();  } } /// <summary> /// 享元工廠,負責(zé)創(chuàng)建和管理享元對象 /// </summary> 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)  {// 更好的實現(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;  } } /// <summary> /// 抽象享元類,提供具體享元類具有的方法 /// </summary> public abstract class Flyweight {  public abstract void Operation(int extrinsicstate); } // 具體的享元對象,這樣我們不把每個字母設(shè)計成一個單獨的類了,而是作為把共享的字母作為享元對象的內(nèi)部狀態(tài) public class ConcreteFlyweight : Flyweight {  // 內(nèi)部狀態(tài)  private string intrinsicstate ;  // 構(gòu)造函數(shù)  public ConcreteFlyweight(string innerState)  {   this.intrinsicstate = innerState;  }  /// <summary>  /// 享元類的實例方法  /// </summary>  /// <param name="extrinsicstate">外部狀態(tài)</param>  public override void Operation(int extrinsicstate)  {   Console.WriteLine("具體實現(xiàn)類: intrinsicstate {0}, extrinsicstate {1}", intrinsicstate, extrinsicstate);  } }

在享元模式的實現(xiàn)中,我們沒有像之前一樣,把一個細粒度的類實例設(shè)計成一個單獨的類,而是把它作為共享對象的內(nèi)部狀態(tài)放在共享類的內(nèi)部定義。

四、享元模式的優(yōu)缺點
分析完享元模式的實現(xiàn)之后,讓我們繼續(xù)分析下享元模式的優(yōu)缺點:

優(yōu)點:

降低了系統(tǒng)中對象的數(shù)量,從而降低了系統(tǒng)中細粒度對象給內(nèi)存帶來的壓力。

缺點:

1.為了使對象可以共享,需要將一些狀態(tài)外部化,這使得程序的邏輯更復(fù)雜,使系統(tǒng)復(fù)雜化。
2.享元模式將享元對象的狀態(tài)外部化,而讀取外部狀態(tài)使得運行時間稍微變長。


五、使用場景
在下面所有條件都滿足時,可以考慮使用享元模式:

  • 一個系統(tǒng)中有大量的對象;
  • 這些對象耗費大量的內(nèi)存;
  • 這些對象中的狀態(tài)大部分都可以被外部化;
  • 這些對象可以按照內(nèi)部狀態(tài)分成很多的組,當(dāng)把外部對象從對象中剔除時,每一個組都可以僅用一個對象代替;
  • 軟件系統(tǒng)不依賴這些對象的身份。

滿足上面的條件的系統(tǒng)可以使用享元模式。但是使用享元模式需要額外維護一個記錄子系統(tǒng)已有的所有享元的表,而這也需要耗費資源,所以,應(yīng)當(dāng)在有足夠多的享元實例可共享時才值得使用享元模式。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 唐山市| 平泉县| 禹城市| 五大连池市| 凌云县| 六盘水市| 湖州市| 商水县| 德庆县| 青川县| 万州区| 梧州市| 鄂托克旗| 广南县| 吐鲁番市| 闸北区| 六盘水市| 南丹县| 五家渠市| 龙井市| 砀山县| 汶上县| 南丰县| 滁州市| 禄丰县| 观塘区| 亳州市| 鄂托克旗| 阿拉善左旗| 宜都市| 南平市| 安义县| 大渡口区| 灵璧县| 剑川县| 白沙| 镇江市| 泗水县| 洪洞县| 涞源县| 岐山县|