当模板方法遇到了委托函数,你的代码又可以精简了
現(xiàn)如今當(dāng)你翻看一些開源項(xiàng)目源碼的時(shí)候,你會(huì)發(fā)現(xiàn)現(xiàn)在到處充斥著委托函數(shù),如Func,Action,Predicate,確實(shí)現(xiàn)在的C#在函數(shù)式編程 的路上越來越成為主流,越來越顯示威力,曾經(jīng)的一些經(jīng)典設(shè)計(jì)模式寫法,在函數(shù)式下可以稍微優(yōu)化一下了,這篇我們就來說說模板方法。
一:實(shí)際場(chǎng)景
1. 模板方法定義
相信這個(gè)模式在平時(shí)開發(fā)中會(huì)經(jīng)常使用到,定義也很簡(jiǎn)單,在父類中定義算法骨架,骨架里面的某些細(xì)節(jié)點(diǎn)由相應(yīng)的子類實(shí)現(xiàn)。
2. 業(yè)務(wù)場(chǎng)景
給用戶推送彩信的時(shí)候,公司需要對(duì)接很多的彩信服務(wù)商,比如說博士通,助通,聯(lián)合維拓,而每一家對(duì)提交彩信的格式有不同的要求, 比如說:博士通和助通會(huì)要求所有的內(nèi)容按指定格式進(jìn)行base64編碼提交過去,聯(lián)合維拓會(huì)要求你按指定格式打包成一個(gè)zip文件流過去, 這就是一個(gè)經(jīng)典的模板模式,可以在父類中定義好構(gòu)造彩信的算法骨架,具體細(xì)節(jié)可以由各自廠家子類實(shí)現(xiàn),為了方便演示畫圖如下:
源碼如下:
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 ProcessRequest(){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 ProcessRequest() { base.ProcessRequest(); }}class LianheweituoTemplate : MmsTemplate{public override string GetHeader() { return "我是聯(lián)合維拓頭!"; }public override string GetTail() { return "我是聯(lián)合維拓體!"; }public override string GetBody() { return "我是聯(lián)合維拓尾!"; }public override void ProcessRequest() { base.ProcessRequest(); }}然后客戶端可以根據(jù)指定通道配置調(diào)用相應(yīng)的子類實(shí)現(xiàn)不同廠家的彩信體構(gòu)建。
二:委托函數(shù)
1. 反思
在面向?qū)ο缶幊陶Z(yǔ)言中,這種寫法都堪稱標(biāo)準(zhǔn),我們先來捋一下流程,子類入口 -> 執(zhí)行父類方法 -> 調(diào)用子類方法?如下圖
從上圖中可以發(fā)現(xiàn)一個(gè)問題,父類在執(zhí)行算法骨架的時(shí)候,為了能夠再次執(zhí)行到該子類方法,在面向?qū)ο缶幊讨斜仨氁褂玫募夹g(shù)就是多態(tài),而為了構(gòu)造多態(tài),就必須在父類中定義一堆方法,然后由子類實(shí)現(xiàn)這一堆方法,這就是你看到的GetHeader(),GetTail(),GetBody()的由來,這時(shí)就顯得有點(diǎn)老態(tài)龍鐘。
2. 回調(diào)函數(shù)
仔細(xì)看一下這個(gè)xmind圖,ZhutongTemplate類調(diào)用的MmsTemplate的方法,MmsTemplate在執(zhí)行的時(shí)候再調(diào)用ZhutongTemplate的方法,前者叫調(diào)用,后者叫回調(diào),如果還不明白,那前者叫送禮,后者叫回禮。。。對(duì),既然在以前是用多態(tài)制造回調(diào),那我是不是可以直接使用C#中的委托函數(shù)更簡(jiǎn)單粗暴呢?
3. 改造模板
直接看代碼吧,千言難抵上代碼。
class MmsTemplate{protected Func<string> header;protected Func<string> body;protected Func<string> tail;public virtual void ProcessRequest(){Console.WriteLine($"1. 彩信頭:{header()}");Console.WriteLine($"2. 彩信體:{header()}");Console.WriteLine($"3. 彩信尾:{tail()}");}}class ZhutongTemplate : MmsTemplate{public override void ProcessRequest(){this.header = () => "我是助通頭!";this.body = () => "我是助通體";this.tail = () => "我是助通尾!";base.ProcessRequest();}}class LianheweituoTemplate : MmsTemplate{public override void ProcessRequest(){this.header = () => "我是聯(lián)合維拓頭!";this.body = () => "我是聯(lián)合維拓體";this.tail = () => "我是聯(lián)合維拓尾!";base.ProcessRequest();}}從上面代碼中可以看到,原來需要多態(tài)實(shí)現(xiàn)的地方直接由委托變量接管,看起來是不是比之前的多態(tài)版簡(jiǎn)潔了很多。
好了,本篇就說到這里,更多的變通玩法期待您的發(fā)現(xiàn)~
總結(jié)
以上是生活随笔為你收集整理的当模板方法遇到了委托函数,你的代码又可以精简了的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Istio Pilot架构解析
- 下一篇: 为什么要用内插字符串代替string.f