av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

面向過程,面向?qū)ο螅瘮?shù)式對同一個問題的思考方式

我之所以對函數(shù)式代碼感興趣是因為函數(shù)式代碼富有表現(xiàn)力,可以使用簡短、緊湊的代碼完成工作,同時能對特定的問題給出優(yōu)雅的解決方案?,F(xiàn)代的編程語言不約而同的朝著面向?qū)ο?、函?shù)式、動態(tài)、解釋執(zhí)行的方向發(fā)展,例如Ruby,Swift。而另一些語言則更加強調(diào)函數(shù)式編程,如F#,Scala,這種語言有著強大的類型推斷系統(tǒng),編寫的代碼潔程度則令人嘆為觀止。

在F#編寫一個兩個數(shù)相加的函數(shù),在F# Interactive中輸入:

1 let add num1 num2=num1*num2;;

F# Interactive為我們推斷了這個函數(shù)類型:val add : num1:int -> num2:int -> int,表示add有兩個int類型的參數(shù)得到了1個int類型。

函數(shù)當(dāng)作參數(shù):

1 2 3 4 5 6 //C# private int Twice(int input,Func f) {     return f(f(input)); } var result = Twice(2, n => n*n);

使用F#則只需要非常簡潔的一個函數(shù)聲明:

1 2 3 4 5 6 > let twice (input:int) f=f(f(input));;   val twice : input:int -> f:(int -> int) -> int   > twice 2 (fun n->n*n);; val it : int = 16

val twice : input:int -> f:(int -> int) –> int 這句話則是F# Interactive給出的推斷:twice函數(shù)需要一個int參數(shù)和一個(int->int)的函數(shù)作為參數(shù),返回一個int.

這兩個例子僅僅是熱身,并不是本篇博客的重點,所以你覺得前兩個例子很無聊或者沒太看明白請繼續(xù)看下面的總結(jié)。

場景:某種活動會有一個日程安排(Schedule),日程安排有3中類型,只舉辦一次(Once),每天一次(Daily),每周一次(Weekly)?;顒訒鶕?jù)日程安排(Schedule)的類型不同具有不同的宣傳內(nèi)容,不同的延期舉行策略。

你對于這樣的場景會有怎么樣的思考呢?

一、面向過程類型的編碼方式

面向過程類型的編碼是需求的直譯過程,代碼會寫成這樣:

1.顯示活動的宣傳內(nèi)容:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public void ShowScheduleDescriptions() {     switch (ScheduleType)     {         case ScheduleType.Once:             Console.WriteLine("this is once activity");             break;         case ScheduleType.Daily:             Console.WriteLine("this is daily activity");             break;         case ScheduleType.Weekly:             Console.WriteLine("this is weekly activity");             break;         default:             throw new InvalidOperationException("unsupported schedule");     } }

這樣的代碼初次看起來沒什么問題,實際存在兩個危險信號:

  • 違反開放封閉(OCP)原則,如果有一天需要加入一種Monthly類型,無疑需要修改這個方法;
  • 這樣的代碼風(fēng)格會讓接下來的開發(fā)者不假思索的進行延續(xù),比方說需要根據(jù)不同的活動類型延期活動;

2. 延期活動:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public void DelaySchedule() {     switch (ScheduleType)     {         case ScheduleType.Once:             Console.WriteLine("Delay one hour");             break;         case ScheduleType.Daily:             Console.WriteLine("Delay one day");             break;         case ScheduleType.Weekly:             Console.WriteLine("Delay one week");             break;         default:             throw new InvalidOperationException("unsupported schedule");     } }

這樣的代格違反了DRY原則,相同的代碼框架卻無法重用。

二、面向?qū)ο蟮木幋a方式

對于一個有經(jīng)驗的OO開發(fā)者,一旦看到switch,if(type=typeof(…))之類的代碼馬上會提高警惕,是不是有一些抽象類型沒有被找出來?在這個例子中則會找出下面的抽象:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public  class Schedule {     public virtual void ShowShowScheduleDescriptions()     {     }       public virtual void DelaySchedule()     {     } }   public class OnceSchedule : Schedule {     public override void ShowShowScheduleDescriptions()     {         Console.WriteLine("this is once activity");     }       public override void DelaySchedule()     {         Console.WriteLine("Delay one hour");     } }   public class DailySchedule : Schedule {     public override void ShowShowScheduleDescriptions()     {         Console.WriteLine("this is daily activity");     }       public override void DelaySchedule()     {         Console.WriteLine("Delay daily day");     } }   //... other schedule

這樣的代碼很好的解決了面向過程代碼的兩個問題,看起來更加具有擴展性,隨著新類型的Schedule引入,舊的代碼完全不用改動。

當(dāng)然事情也不是絕對的,什么情況下需要改動舊代碼呢?當(dāng)需要擴展Schedule的行為的時候,例如需求升級,不同的Schedule具有不同的舉辦方式,我們不得不在每種Schedule中加入一個 void Hold()方法。

三、函數(shù)式解決方案

函數(shù)式語言則使用可區(qū)分聯(lián)合和模式匹配來處理此類問題。

定義一個Schedule可區(qū)分聯(lián)合:

1 2 3 4 type Schedule= | Once of DateTime | Daily of DateTime*int | Weekly of DateTime*int

這個類型既說明了Schedule有三個不同的類型,同時定義了三種類型分別具有的數(shù)據(jù)結(jié)構(gòu)。像是Enum和類的綜合體,但是又顯得特別精致。

1.顯示活動的宣傳內(nèi)容,使用了模式匹配:

1 2 3 4 5 let ShowShowScheduleDescriptions schedule= match schedule with | Once(DateTime)-> printfn "this is once activity" | Daily(DateTime,int)->printfn "this is daily activity" | Weekly(DateTime,int)->printfn "this is weekly activity"

這個方法類似于switch…case,但是通過匹配可區(qū)分聯(lián)合來實現(xiàn),而不是通過一個顯示的Enum來實現(xiàn)。

2. 延期活動:

1 2 3 4 5 let DelaySchedule schedule= match schedule with | Once(DateTime)-> printfn "Delay one hour" | Daily(DateTime,int)->printfn "Delay one day" | Weekly(DateTime,int)->printfn "Delay one week"

函數(shù)式編程的解決方案認為可以很方便的添加新的行為,例如增加新的行為:Hold()。通過定義可區(qū)分聯(lián)合和模式匹配來完成編碼,整個解決方案像是面向過程和面向?qū)ο蟮囊环N結(jié)合體,但是側(cè)重點不同,實現(xiàn)的代碼也更加精致。


名稱欄目:面向過程,面向?qū)ο?,函?shù)式對同一個問題的思考方式
分享路徑:http://uogjgqi.cn/article/dpphjie.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流