現現在當你翻看一些開源項目源碼的時候,你會發現如今處處充斥着委託函數,如Func,Action,Predicate,確實如今的C#在函數式編程 的路上愈來愈成爲主流,愈來愈顯示威力,曾經的一些經典設計模式寫法,在函數式下能夠稍微優化一下了,這篇咱們就來講說模板方法。算法
1. 模板方法定義編程
相信這個模式在平時開發中會常常使用到,定義也很簡單,在父類中定義算法骨架,骨架裏面的某些細節點由相應的子類實現。設計模式
2. 業務場景編程語言
給用戶推送彩信的時候,公司須要對接不少的彩信服務商,好比說博士通,助通,聯合維拓,而每一家對提交彩信的格式有不一樣的要求, 好比說:博士通和助通會要求全部的內容按指定格式進行base64編碼提交過去,聯合維拓會要求你按指定格式打包成一個zip文件流過去, 這就是一個經典的模板模式,能夠在父類中定義好構造彩信的算法骨架,具體細節能夠由各自廠家子類實現,爲了方便演示畫圖以下:ide
源碼以下:函數式編程
class MmsTemplate { public virtual string GetHeader() { return string.Empty; } public virtual string GetBody() { return string.Empty; } public virtual string GetTail() { return string.Empty; } public virtual void Proce***equest() { Console.WriteLine($"1. 彩信頭:{GetHeader()}"); Console.WriteLine($"2. 彩信體:{GetBody()}"); Console.WriteLine($"3. 彩信尾:{GetTail()}"); } } class ZhutongTemplate : MmsTemplate { public override string GetHeader() { return "我是助通頭!"; } public override string GetTail() { return "我是助通體!"; } public override string GetBody() { return "我是助通尾!"; } public override void Proce***equest() { base.Proce***equest(); } } class LianheweituoTemplate : MmsTemplate { public override string GetHeader() { return "我是聯合維拓頭!"; } public override string GetTail() { return "我是聯合維拓體!"; } public override string GetBody() { return "我是聯合維拓尾!"; } public override void Proce***equest() { base.Proce***equest(); } }
而後客戶端能夠根據指定通道配置調用相應的子類實現不一樣廠家的彩信體構建。函數
1. 反思優化
在面向對象編程語言中,這種寫法都堪稱標準,咱們先來捋一下流程,子類入口 -> 執行父類方法 -> 調用子類方法 以下圖
this
從上圖中能夠發現一個問題,父類在執行算法骨架的時候,爲了可以再次執行到該子類方法,在面向對象編程中必需要使用的技術就是多態,而爲了構造多態,就必須在父類中定義一堆方法,而後由子類實現這一堆方法,這就是你看到的GetHeader(),GetTail(),GetBody()的由來,這時就顯得有點老態龍鍾。編碼
2. 回調函數
仔細看一下這個xmind圖,ZhutongTemplate類調用的MmsTemplate的方法,MmsTemplate在執行的時候再調用ZhutongTemplate的方法,前者叫調用,後者叫回調,若是還不明白,那前者叫送禮,後者叫回禮。。。對,既然在之前是用多態製造回調,那我是否是能夠直接使用C#中的委託函數更簡單粗暴呢?
3. 改造模板
直接看代碼吧,千言難抵上代碼。
class MmsTemplate { protected Func<string> header; protected Func<string> body; protected Func<string> tail; public virtual void Proce***equest() { Console.WriteLine($"1. 彩信頭:{header()}"); Console.WriteLine($"2. 彩信體:{header()}"); Console.WriteLine($"3. 彩信尾:{tail()}"); } } class ZhutongTemplate : MmsTemplate { public override void Proce***equest() { this.header = () => "我是助通頭!"; this.body = () => "我是助通體"; this.tail = () => "我是助通尾!"; base.Proce***equest(); } } class LianheweituoTemplate : MmsTemplate { public override void Proce***equest() { this.header = () => "我是聯合維拓頭!"; this.body = () => "我是聯合維拓體"; this.tail = () => "我是聯合維拓尾!"; base.Proce***equest(); } }
從上面代碼中能夠看到,原來須要多態實現的地方直接由委託變量接管,看起來是否是比以前的多態版簡潔了不少。
好了,本篇就說到這裏,更多的變通玩法期待您的發現~