新聞中心
雖然泛型出現(xiàn)已有多年,連Java都早已借鑒引入了泛型(雖然是語法糖),可是用泛型的編程思維方式并沒有得到相應(yīng)的普及。一方面是由于過去大量的Framework仍然是在非泛型時代寫成的,另一方面泛型的設(shè)計(jì)模式?jīng)]有得到發(fā)展,改變的時候該到了。

創(chuàng)新互聯(lián)公司專注于焦作網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供焦作營銷型網(wǎng)站建設(shè),焦作網(wǎng)站制作、焦作網(wǎng)頁設(shè)計(jì)、焦作網(wǎng)站官網(wǎng)定制、微信平臺小程序開發(fā)服務(wù),打造焦作網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供焦作網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
來舉一個例子說明這兩點(diǎn)。我們?nèi)绻麑戇^網(wǎng)絡(luò)數(shù)據(jù)抓取的代碼,應(yīng)該熟悉這樣的代碼:
- var request = WebRequest.Create("http://www.cnblogs.com/") as HttpWebRequest;
或者這么寫,也是一樣:
- var request = HttpWebRequest.Create("http://www.cnblogs.com/") as HttpWebRequest;
大家可想過,為什么每次都要as一下?
類似的情況還有,比如做圖像處理的弟兄會熟悉:
- var bm = Image.FromFile("e:\\me.jpg") as Bitmap;
和
- var bm = Bitmap.FromFile("e:\\me.jpg") as Bitmap;
我想過,但沒想明白。上面兩種寫法,都是調(diào)用父類的工廠方法,實(shí)際返回了一個子類的實(shí)例。顯然,即使不了解OCP,憑直覺也應(yīng)該想到,父類的實(shí)現(xiàn)中不應(yīng)該被子類所決定。寫WebRequest和Image的前輩可能也覺得直接返回子類實(shí)例不妥,所以陰險地把方法簽名的返回類型改成了父類。
雖然這種行徑值得嚴(yán)重鄙視。但.NET程序員大都是人云亦云,照葫蘆畫瓢的好學(xué)生,所以這個問題多年了也沒有修改。
理想的設(shè)計(jì)應(yīng)該是這樣:父類的每個子類,都有獨(dú)立的工廠方法,返回其自身的實(shí)例。這樣做法,在泛型出現(xiàn)前非常笨拙,得不償失,但有了泛型,就可以精巧地實(shí)現(xiàn)。
以模擬Image類為例,Image和BitMap實(shí)現(xiàn)如下:
- class Image
where T:Image , new() - {
- public string Path { get; set; }
- public static T FromFile(string path)
- {
- return new T() { Path = path };
- }
- }
- class Bitmap:Image
- {
- }
Image自身的工廠方法,就沒有存在的必要了。
可以簡單地測試一下:
- var path = @"e:\me.jpg";
- var bm = Bitmap.FromFile(path); ;
- Console.WriteLine(bm.Path);
- Console.WriteLine(bm.GetType().Name);
輸出結(jié)果如下:
- Path: e:\me.jpg
- Type: Bitmap
為了讓大家更熟悉一下,再舉一個實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)中的二叉樹作例子。
傳統(tǒng)的樹節(jié)點(diǎn)類,無論無論C/C++/Java都是類似這樣:
- class TreeNode
- {
- public TreeNode LeftChild { get; set; }
- public TreeNode RightChild { get; set; }
- public TreeNode Parent { get; set; }
- public int Value { get; set; }
- }
大家知道,二叉樹又分好幾種,AVL樹、B樹、紅黑樹等等。實(shí)現(xiàn)特殊的二叉樹數(shù)據(jù)結(jié)構(gòu),勢必要繼承TreeNode。由于樹節(jié)點(diǎn)的類型中,有類型為基類的成員,所以在子類操作這些成員時,往往也要強(qiáng)制轉(zhuǎn)換類型,這比Image和WebRequest的例子,只在實(shí)例創(chuàng)建時轉(zhuǎn)換類型還麻煩。
這就該泛型模式一顯身手的好機(jī)會了,請看其父類型的實(shí)現(xiàn):
- ///
Type of the node. - ///
Type of the node value. - class TreeNode
where T:TreeNode where K: IComparable - {
- public T LeftChild { get; set; }
- public T RightChild { get; set; }
- public T Parent { get; set; }
- public K Value { get; set; }
- }
之后,實(shí)現(xiàn)任何一種特殊二叉樹結(jié)構(gòu),比如RBTreeNode代表紅黑樹節(jié)點(diǎn),可以這樣:
- class RBTreeNode : TreeNode
- {
- ///
- /// 樹節(jié)點(diǎn)顏色,是否為紅。
- ///
- public bool IsRed { get; set; }
- public override string ToString()
- {
- return this.Value + "," + (this.IsRed ? "R" : "B");
- }
- }
這個是AVL樹:
- class AvlTreeNode : TreeNode
- {
- ///
- /// 節(jié)點(diǎn)的平衡度
- ///
- public int Balance { get; set; }
- public override string ToString()
- {
- return "Balance: " + Balance + ", Value: " + this.Value;
- }
- }
不但完全符合OCP原則,而且再也不需要as來強(qiáng)制轉(zhuǎn)換節(jié)點(diǎn)類型了。
這肯定不是我的首創(chuàng),其實(shí).NET Framework中已經(jīng)不少這樣的設(shè)計(jì),比如IComparable
看上去也很簡單吧,但是很多人思維還停留在面向?qū)ο笳Z言剛誕生的階段,還不習(xí)慣用這種設(shè)計(jì)模式。我認(rèn)為這種寫法足夠典型和通用,足以得上一種設(shè)計(jì)模式,而且是.NET特殊優(yōu)勢,獨(dú)特魅力。
說到設(shè)計(jì)模式,其實(shí)GOF提出的23種設(shè)計(jì)模式多年了,已經(jīng)過時,出現(xiàn)了許多新模式(比如并發(fā)編程方面,參考Wiki Design Pattern)。舊有的模式中,有的已經(jīng)包含在.NET語言特性中,有的模式實(shí)現(xiàn)方式已經(jīng)改頭換面。尤其在泛型出現(xiàn)后,許多模式的實(shí)現(xiàn)可以變得簡潔許多,優(yōu)雅許多。
不要一遍遍炒過去的冷飯,設(shè)計(jì)模式應(yīng)該與時俱進(jìn),永遠(yuǎn)是充滿新鮮活力的話題。
原文來自:http://www.cnblogs.com/XmNotes/archive/2012/04/23/2466938.html
【編輯推薦】
- 為什么我不再做.NET開發(fā)
- 詳細(xì)解讀ASP.NET的異步
- ASP.NET的路由系統(tǒng):URL與物理文件的分離
- ASP.NET MVC3 從零開始一步步構(gòu)建Web
- Node.js vs Opa: Web框架殺手
文章題目:淺談.NET獨(dú)有精巧泛型設(shè)計(jì)模式
瀏覽路徑:http://fisionsoft.com.cn/article/dhjojcg.html


咨詢
建站咨詢
