能夠這麼說,不懂設計模式,難以理解面向對象的思想。也能夠反過來講,不理解面向對象的思想,很難理解設計模式。不是嗎?數據庫
今天我要和你們說一說c#實現模板模式,這是一個很是經常使用,而且簡單的模式,在衆多的設計模式中,這是我用的最多,並且是天然而然地應用,沒有擔憂過什麼。c#
曾幾什麼時候,模板模式悄悄地跑到個人代碼裏面了,也許是我看別人的代碼時,不當心學到的。設計模式
有這麼一個場景:我須要作「我的成果導出」和「管理後臺的成果導出」,兩個模塊的實現的功能是同樣的,都是在頁面上展現成果列表,而後能夠管理、查詢、導出成果。至於具體如何展現,展現哪些數據,也就是具體的操做固然不同了。也有一部分代碼是相同的,好比說我要刪除一條成果,是否是實現一致呢?只要你給一個id,我操做數據庫,便刪除了。難道這樣的代碼,我還須要拷貝兩份?有人說,你爲何要弄兩份呢,你寫一個公共的方法,到時候調用便可。這貌似不錯的解決辦法。不過此解決方法遇到這種狀況,怎麼辦呢?一個方法A的大部分代碼都相同,就是有一些地方不一樣,這時候,咱們還能提出來,做爲公共的方法調用嗎?有人說,你傻呀,你把大部分相同的代碼提出來,做爲公共的地方調用。那這樣作,這個A方法,不是仍是拷貝了兩份?ide
這種狀況下,個人模板方法該是時候出場了,且看代碼:工具
解釋下代碼,我首先定義了一個抽象的控制器,因爲首頁的顯示,不論是後臺的,仍是我的導出的,它們都是如此作法:設計
一、判斷viewmodel是否爲空3d
二、綁定頁面下拉列表對象
三、填充viewmodelblog
四、返回視圖排序
其中2和3兩步,後臺和我的導出的實現是不一樣的。後臺的下拉列表更豐富些,viewmodel展現的字段也多點。因此,咱們把2和3抽象出來,做爲抽象方法。到具體運行時,決定到底調用後臺導出的,仍是我的導出的方法實現。由於,在編譯階段,咱們也無法肯定它到底調用哪一個方法,由於它是抽象的。
且看管理後臺的成果導出實現代碼:
下面是我的成果導出的代碼實現:
看代碼,兩個類名都起得同樣,很差意思了,這兩個類不在一個命名空間下。不過這樣會給人形成閱讀上的誤會。那麼有人會說,你上面的代碼不是重複的嗎?我說,不能看表面的,我是盡最大可能複用。不信,你看下面的代碼:
管理後臺的成果導出下拉列表綁定:
public override void BindSelect(ExportViewModel viewModel)
{
//學科類型綁定
ViewData["subjectTypes"] = SelectHelp.BindSelect<SubjectType>("學科系統");
//機構排名
ViewData["OrganizationOrders"] = new List<SelectListItem>()
{
new SelectListItem { Text = "本機構排名", Value = "-1"},
new SelectListItem { Text = "1", Value = "1"},
new SelectListItem { Text = ">1", Value = "2"},
new SelectListItem { Text = "2", Value = "3"},
new SelectListItem { Text = "<=2", Value = "4"},
new SelectListItem { Text = ">2", Value = "5"}
};
}
我的成果導出的下拉列表綁定:
public override void BindSelect(ExportViewModel viewModel)
{
//審覈狀態
ViewData["ReviewStates"] = new List<SelectListItem>()
{
new SelectListItem { Text = "審覈狀態", Value = "-1"},
new SelectListItem { Text = "待審覈", Value = "1" },
new SelectListItem { Text = "審覈經過", Value = "2"},
new SelectListItem { Text = "審覈未經過", Value = "3"},
//new SelectListItem { Text = "自動審覈中", Value = "4"},
new SelectListItem { Text = "撤回", Value = "5"},
new SelectListItem { Text = "禁止", Value = "6"}
};
//署名狀況
ViewData["Bylines"] = new List<SelectListItem>()
{
new SelectListItem { Text = "署名狀況", Value = "-1"},
new SelectListItem { Text = "第一做者", Value = "1" },
new SelectListItem { Text = "通訊做者", Value = "2"},
new SelectListItem { Text = "通訊做者或者第一做者", Value = "3"}
//new SelectListItem { Text = "非第一和通訊做者", Value = "4"}
};
//排序
ViewData["Orders"] = new List<SelectListItem>()
{
new SelectListItem { Text = "提交日期", Value = "1"},
new SelectListItem { Text = "年度", Value = "0"}
};
}
模板模式,體現了代碼複用的思想,也體現了面向對象中的多態。有人說,你定義的抽象方法,子類要實現,這些不都重複嗎?我說的是,模板方法還有一個特色,就是咱們的代碼主幹邏輯很是清晰,易於閱讀,也好修改。若是說一味地提取公共方法,而後調用,最後也很差改,公共方法做爲」公共服務「」,萬一不能知足個別」客戶端「,也就是調用端的需求,咱們怎麼辦呢?此時,抽象類的繼承機制,能夠解決問題。
固然不能說公共類做爲公共服務就很差,就看什麼場合了。好比說,我們常常用的工具類,處理字符串的,日期的,數據庫操做的。這些工具類是很是有幫助的,也很是好的體現了代碼複用原則。好了,模板模式就介紹到這裏。