|
一、上篇回顧
通過(guò)上篇的講述,我們知道裝飾模式,特別適合對(duì)某個(gè)類(lèi)型的對(duì)象,動(dòng)態(tài)的增加新的職責(zé),應(yīng)用程序就像使用原來(lái)的對(duì)象一樣使用對(duì)象新增的裝飾后的功能,裝 飾模式就好像是穿了一層層的外殼,這樣的方式避免了通過(guò)繼承來(lái)為類(lèi)型添加新的職責(zé)的形式可取,通過(guò)繼承的方式容易造成子類(lèi)的膨脹,但是當(dāng)裝飾類(lèi)太多的時(shí) 候,也是個(gè)難以維護(hù)的問(wèn)題,至少是在裝飾對(duì)象的時(shí)候,我們可能需要多步操作來(lái)完成對(duì)象的裝飾,這時(shí)候我們可以同上面提出的改進(jìn)的方案,來(lái)完成自動(dòng)配置裝飾 模式,記錄操作模式的狀態(tài),可以進(jìn)行有效的回滾操作,以完成撤銷(xiāo)操作。
我們先來(lái)回顧下裝飾模式的使用場(chǎng)景:
1、當(dāng)我們需要為某個(gè)現(xiàn)有的對(duì)象,動(dòng)態(tài)的增加一個(gè)新的功能或職責(zé)時(shí),可以考慮使用裝飾模式。
2、適應(yīng)于某個(gè)對(duì)象的職責(zé)經(jīng)常發(fā)生變化或者經(jīng)常需要?jiǎng)討B(tài)的增加職責(zé),避免因?yàn)檫@種為了適應(yīng)這樣的變化,而增加繼承子類(lèi)擴(kuò)展的方式,因?yàn)檫@種方式為 造成,子類(lèi)膨脹的速度過(guò)快,難以控制。
二、摘要
本篇我們將會(huì)講述結(jié)構(gòu)性模式中的另外一個(gè)非常有用的模式-享元模式,享元模式的特點(diǎn)是,復(fù)用我們內(nèi)存中已存在的對(duì)象,降低系統(tǒng)創(chuàng)建對(duì)象實(shí)例的性能消耗。在.NET下的值類(lèi)型和引用類(lèi)型的內(nèi)存分配機(jī)制,我這里就不做詳細(xì)的講解了,包括引用類(lèi)型與值類(lèi)型之間的裝箱和拆箱的操作,這個(gè)具體的可以參考園子里面的關(guān)于這方面的文章的討論。
我們來(lái)給出個(gè)簡(jiǎn)單的享元模式的應(yīng)用前后的對(duì)比圖,大概我們就知道享元模式的重要作用了。
我們這里以繪制一個(gè)有樣式的字體來(lái)說(shuō)明吧,有的時(shí)候我們想繪制一個(gè)純色的文字,比如紅色,那么我們可能需要?jiǎng)?chuàng)建很多的實(shí)例,通常來(lái)說(shuō),這些實(shí)例的差別不大,這個(gè)時(shí)候,我們可以考慮復(fù)用其中創(chuàng)建的某個(gè)實(shí)例,而不用去new這么多相同的對(duì)象,來(lái)完成這樣的工作。我們下面以這個(gè)例子來(lái)說(shuō)明,使用享元模式的前后對(duì)比的情況。
通過(guò)上圖我們可以大概的看出享元模式的目的是什么,本篇將會(huì)從以下幾點(diǎn)出發(fā),講述享元模式的應(yīng)用。
1、享元模式的特點(diǎn)和場(chǎng)景。
2、享元模式的經(jīng)典實(shí)現(xiàn)。
3、享元模式的其他方案。
4、享元模式小結(jié)。
下面我們來(lái)看下享元模式的類(lèi)圖吧:
三、本文大綱
a、上篇回顧。
b、摘要。
c、本文大綱。
d、享元模式的特點(diǎn)及使用場(chǎng)景。
e、享元模式的經(jīng)典實(shí)現(xiàn)。
f、享元模式的其他方案。
g、享元模式使用總結(jié)。
四、享元模式的特點(diǎn)及使用場(chǎng)景
4.1、享元模式的特點(diǎn)
享元模式的意圖是通過(guò)共享有效支持大量細(xì)粒度的對(duì)象,來(lái)提供應(yīng)用程序的性能,節(jié)省系統(tǒng)中重復(fù)創(chuàng)建對(duì)象實(shí)例的性能消耗,這個(gè)怎么理解呢?其實(shí)就是以下幾點(diǎn)的含義:
1、當(dāng)我們系統(tǒng)中某個(gè)對(duì)象類(lèi)型的實(shí)例較多的情況。
2、并且要求這些實(shí)例進(jìn)行分類(lèi)后,發(fā)現(xiàn)真正有區(qū)別的分類(lèi)很少的情況。
例如我們的生活中很多的場(chǎng)景,我們?cè)谑褂闷匆糨斎氲姆ǖ臅r(shí)候,如果說(shuō)我們每個(gè)字都是new一個(gè)對(duì)象實(shí)例的操作的話,那么內(nèi)存中的實(shí)例就太可怕,這個(gè)時(shí)候,我們是不是可以考慮將這些重復(fù)的字體在內(nèi)存中只是創(chuàng)建一次,而是通過(guò)復(fù)用對(duì)象的形式,來(lái)組織一些可能有多個(gè)字符重復(fù)的內(nèi)容呢?也許這是一個(gè)不錯(cuò)的主意,我們來(lái)看看這個(gè)示例的過(guò)程吧。
4.2、享元模式的使用場(chǎng)景
1、當(dāng)我們發(fā)現(xiàn)某個(gè)類(lèi)型的對(duì)象有大量的實(shí)例時(shí),我們是否可以對(duì)這些實(shí)例進(jìn)行分類(lèi),經(jīng)過(guò)分類(lèi)后,我們發(fā)現(xiàn)只有很少的類(lèi)別的情況下。
2、我們發(fā)現(xiàn)通過(guò)使用享元模式后能夠提高系統(tǒng)的性能和不會(huì)帶來(lái)更多的復(fù)雜度時(shí)。
享元模式一般是給出本地內(nèi)存資源節(jié)省的一個(gè)方案,并不適合互聯(lián)網(wǎng)上的分布式應(yīng)用的情況,不過(guò)享元模式對(duì)于排他性的要求資源的控制,是個(gè)不錯(cuò)的選擇的。
五、享元模式的經(jīng)典實(shí)現(xiàn)
我們下面來(lái)根據(jù)上面的我們對(duì)輸入法中的字體來(lái)進(jìn)行分析,給出相關(guān)的示例代碼:
字體類(lèi)型的基類(lèi):
public class FontBase
{
private List<string> font = new List<string>();
private string fontName;
public FontBase(string name)
{
this.fontName = name;
}
public FontBase AddFont(string font)
{
this.font.Add(font);
return this;
}
public virtual string FontName
{
get
{
return this.fontName;
}
}
}
具體的文字類(lèi)型類(lèi):
public class ChineseFont : FontBase
{
public ChineseFont()
: base("ChineseFont")
{
base.AddFont("ChineseFont");
}
}
public class EnglishFont : FontBase
{
public EnglishFont()
: base("EnglishFont")
{
base.AddFont("EnglishFont");
}
}
具體的創(chuàng)建工廠類(lèi):
public class FontFactory
{
private Dictionary<string, FontBase> fonts = new Dictionary<string, FontBase>();
public FontBase Create(string name)
{
FontBase fontBase = fonts[name];
if (fontBase != null)
return fontBase;
fontBase = (FontBase)Activator.CreateInstance(Type.GetType(name));
return fontBase;
}
}
it知識(shí)庫(kù):系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式—享元模式,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。