成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面向過程,面向對象,函數式對同一個問題的思考方式

開發 后端
我之所以對函數式代碼感興趣是因為函數式代碼富有表現力,可以使用簡短、緊湊的代碼完成工作,同時能對特定的問題給出優雅的解決方案?,F代的編程語言不約而同的朝著面向對象、函數式、動態、解釋執行的方向發展,例如Ruby,Swift。

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

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

1
let add num1 num2=num1*num2;;

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

函數當作參數:

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

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

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函數需要一個int參數和一個(int->int)的函數作為參數,返回一個int.

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

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

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

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

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

1.顯示活動的宣傳內容:

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類型,無疑需要修改這個方法;
  • 這樣的代碼風格會讓接下來的開發者不假思索的進行延續,比方說需要根據不同的活動類型延期活動;

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原則,相同的代碼框架卻無法重用。

二、面向對象的編碼方式

對于一個有經驗的OO開發者,一旦看到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引入,舊的代碼完全不用改動。

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

三、函數式解決方案

函數式語言則使用可區分聯合和模式匹配來處理此類問題。

定義一個Schedule可區分聯合:

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

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

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

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,但是通過匹配可區分聯合來實現,而不是通過一個顯示的Enum來實現。

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"

函數式編程的解決方案認為可以很方便的添加新的行為,例如增加新的行為:Hold()。通過定義可區分聯合和模式匹配來完成編碼,整個解決方案像是面向過程和面向對象的一種結合體,但是側重點不同,實現的代碼也更加精致。

責任編輯:李英杰 來源: 博客園
相關推薦

2022-07-30 23:41:53

面向過程面向對象面向協議編程

2016-12-15 08:54:52

線程sessionopenSession

2010-07-15 13:56:24

面向對象面向過程

2023-11-30 08:00:54

面向對象面向切面

2013-11-26 10:14:15

面向對象函數式

2009-09-27 15:29:00

Scala講座面向對象Scala

2009-07-08 16:10:24

Scala簡介面向對象函數式

2022-03-26 09:32:54

Python編程映射

2023-01-10 09:38:09

面向對象系統

2011-06-02 09:47:11

C語言重構

2020-10-26 12:27:18

對象編程函數式

2011-01-19 10:50:31

軟件設計師

2010-07-08 13:35:39

UML面向對象

2021-05-06 21:49:56

索引掃描次序

2013-03-11 09:23:22

Go語言面向對象

2011-05-25 11:15:02

Javascript繼承

2021-08-16 20:48:34

嵌入式單片機信息

2011-05-25 10:21:44

Javascript

2022-08-08 08:25:21

Javajar 文件

2016-12-20 13:55:52

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久精品无码一区二区三区 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 欧美精品久久久 | 亚洲免费视频播放 | 亚洲精精品 | 超碰在线免费公开 | av一区二区三区 | 日韩1区 | 国产在线一区二区三区 | 成人高清视频在线观看 | 成人精品鲁一区一区二区 | 日韩国产欧美一区 | 亚洲一区国产 | 宅女噜噜66国产精品观看免费 | 亚洲一区二区三区四区五区午夜 | 日本网站在线看 | 久视频在线观看 | 在线观看中文字幕dvd播放 | 97色在线视频 | 最新高清无码专区 | 日韩一区二区三区在线观看 | 国产成人精品免高潮在线观看 | 天堂在线1| 亚洲成人一级 | 精品国产精品一区二区夜夜嗨 | 国产精品69毛片高清亚洲 | 99热免费在线| 99久久夜色精品国产亚洲96 | 美女一级毛片 | 久久久日韩精品一区二区三区 | 久草色视频 | 国产精品免费一区二区三区四区 | 成人av在线播放 | 一二区成人影院电影网 | 亚洲综合精品 | 99精品福利视频 | 午夜影院在线观看免费 | 亚洲精品播放 | 99久久精品国产一区二区三区 | 国产一级片精品 | 久久精品色欧美aⅴ一区二区 |