講授C#設計形式編程中享元形式的應用。本站提示廣大學習愛好者:(講授C#設計形式編程中享元形式的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是講授C#設計形式編程中享元形式的應用正文
1、概述
在軟件開辟中,我們有時須要創立年夜量細粒度的對象,好比文檔處置體系便可能須要創立不計其數的字符對象。但假如對每一個字符對象都分派內存,那末在體系運轉時就會消耗年夜量的內存。若何在保存面向對象操作方法長處的同時防止創立年夜量的對象呢?這就到了享元形式施展感化的時刻了。
2、享元形式
享元形式應用同享技巧有用地支撐年夜量細粒度的對象。例如可以對文檔處置體系創立同享池,在同享池中樹立字母和代碼的對應關系,如許便可以用同享池中的26個對象處理須要創立年夜量對象的成績。其構造圖以下:

Flyweight界說了享元接口,內部對象經由過程這個接口來拜訪詳細的享元對象。
ConcreteFlyweight完成Flyweight接口,界說了詳細的享元對象,並保留享元對象的外部狀況。該享元對象是可同享的。
UnsharedConcreteFlyweight完成Flyweight接口,界說了不消於同享的享元對象。
FlyweightFactory創立並治理享元對象。
Client保留對享元接口的援用,經由過程該援用有用的應用詳細的享元對象。
3、示例
上面以一個現實的運用來完成下享元形式。這個例子是:一個文本編纂器中會湧現許多字面,應用享元形式去完成這個文本編纂器的話,會把每一個字面做成一個享元對象。享元對象的外部狀況就是這個字面,而字母在文本中的地位和字體作風等其他信息就是它的內部狀況。上面就以這個例子來完成下享元形式,詳細完成代碼以下:
/// <summary>
/// 客戶端挪用
/// </summary>
class Client
{
static void Main(string[] args)
{
// 界說內部狀況,例如字母的地位等信息
int externalstate = 10;
// 初始化享元工場
FlyweightFactory factory = new FlyweightFactory();
// 斷定能否曾經創立了字母A,假如曾經創立就直接應用創立的對象A
Flyweight fa = factory.GetFlyweight("A");
if (fa != null)
{
// 把內部狀況作為享元對象的辦法挪用參數
fa.Operation(--externalstate);
}
// 斷定能否曾經創立了字母B
Flyweight fb = factory.GetFlyweight("B");
if (fb != null)
{
fb.Operation(--externalstate);
}
// 斷定能否曾經創立了字母C
Flyweight fc = factory.GetFlyweight("C");
if (fc != null)
{
fc.Operation(--externalstate);
}
// 斷定能否曾經創立了字母D
Flyweight fd= factory.GetFlyweight("D");
if (fd != null)
{
fd.Operation(--externalstate);
}
else
{
Console.WriteLine("駐留池中不存在字符串D");
// 這時候候就須要創立一個對象並放入駐留池中
ConcreteFlyweight d = new ConcreteFlyweight("D");
factory.flyweights.Add("D", d);
}
Console.Read();
}
}
/// <summary>
/// 享元工場,擔任創立和治理享元對象
/// </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)
{
// 更好的完成以下
//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);
}
// 詳細的享元對象,如許我們不把每一個字母設計成一個零丁的類了,而是作為把同享的字母作為享元對象的外部狀況
public class ConcreteFlyweight : Flyweight
{
// 外部狀況
private string intrinsicstate ;
// 結構函數
public ConcreteFlyweight(string innerState)
{
this.intrinsicstate = innerState;
}
/// <summary>
/// 享元類的實例辦法
/// </summary>
/// <param name="extrinsicstate">內部狀況</param>
public override void Operation(int extrinsicstate)
{
Console.WriteLine("詳細完成類: intrinsicstate {0}, extrinsicstate {1}", intrinsicstate, extrinsicstate);
}
}
在享元形式的完成中,我們沒有像之前一樣,把一個細粒度的類實例設計成一個零丁的類,而是把它作為同享對象的外部狀況放在同享類的外部界說。
4、享元形式的優缺陷
剖析完享元形式的完成以後,讓我們持續剖析下享元形式的優缺陷:
長處:
下降了體系中對象的數目,從而下降了體系中細粒度對象給內存帶來的壓力。
缺陷:
1.為了使對象可以同享,須要將一些狀況內部化,這使得法式的邏輯更龐雜,使體系龐雜化。
2.享元形式將享元對象的狀況內部化,而讀取內部狀況使得運轉時光略微變長。
5、應用場景
鄙人面一切前提都知足時,可以斟酌應用享元形式:
知足下面的前提的體系可使用享元形式。然則應用享元形式須要額定保護一個記載子體系已有的一切享元的表,而這也須要消耗資本,所以,應該在有足夠多的享元實例可同享時才值得應用享元形式。