現如今當你翻看一些開源專案原始碼的時候,你會發現現在到處充斥著委托函式,如Func,Action,Predicate,確實作在的C#在函式式編程的路上越來越成為主流,越來越顯示威力,曾經的一些經典設計模式寫法,在函式式下可以稍微優化一下了,這篇我們就來說說模板方法,
一:實際場景
1. 模板方法定義
相信這個模式在平時開發中會經常使用到,定義也很簡單,在父類中定義演算法骨架,骨架里面的某些細節點由相應的子類實作,
2. 業務場景
給用戶推送彩信的時候,公司需要對接很多的彩信服務商,比如說博士通,助通,聯合維拓,而每一家對提交彩信的格式有不同的要求,比如說:博士通和助通會要求所有的內容按指定格式進行base64編碼提交過去,聯合維拓會要求你按指定格式打包成一個zip檔案流過去,這就是一個經典的模板模式,可以在父類中定義好構造彩信的演算法骨架,具體細節可以由各自廠家子類實作,為了方便演示畫圖如下:

原始碼如下:
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 "我是聯合維拓頭!"; }
public override string GetTail() { return "我是聯合維拓體!"; }
public override string GetBody() { return "我是聯合維拓尾!"; }
public override void ProcessRequest() { base.ProcessRequest(); }
}
然后客戶端可以根據指定通道配置呼叫相應的子類實作不同廠家的彩信體構建,

二:委托函式
1. 反思
在面向物件編程語言中,這種寫法都堪稱標準,我們先來捋一下流程,子類入口 -> 執行父類方法 -> 呼叫子類方法 如下圖

從上圖中可以發現一個問題,父類在執行演算法骨架的時候,為了能夠再次執行到該子類方法,在面向物件編程中必須要使用的技術就是多型,而為了構造多型,就必須在父類中定義一堆方法,然后由子類實作這一堆方法,這就是你看到的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 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 = () => "我是聯合維拓頭!";
this.body = () => "我是聯合維拓體";
this.tail = () => "我是聯合維拓尾!";
base.ProcessRequest();
}
}
從上面代碼中可以看到,原來需要多型實作的地方直接由委托變數接管,看起來是不是比之前的多型版簡潔了很多,
好了,本篇就說到這里,更多的變通玩法期待您的發現~
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/52816.html
標籤:C#
上一篇:多執行緒之旅(Task 任務)
