版權申明:本文為博主窗戶(Colin Cai)原創,歡迎轉帖。如要轉貼,必須注明原文網址 http://www.cnblogs.com/Colin-Cai/p/9431665.html 作者:窗戶 QQ/微信:6679072 E-mail:6679072@qq.com
我這里以炒菜為例來給出各種編程范式的示例。
過程式編程
生活的經驗告訴我們以下的物理現實,事情是按照時間的順序一個步驟接一個步驟的發展。編程里有一個范式就模擬了這樣的經驗,就是過程式編程。
如果現在有一些剛從超市買回來的菜,要吃進肚子,按照過程式編程,可以如下表示:
洗(菜)
切(菜)
炒(菜)
吃(菜)
以上的代碼中,括號外為動詞,括號內為名詞。熟悉過程式的我們都知道,這里動詞對應於函數,名詞對應於函數的參數。
函數式編程
我們觀察上述的過程式編程對於炒菜這個問題描述,不難發現,這四步的名詞都是菜,但動詞卻不一樣。
於是我們換個思想,我們所要做的實際上都是不斷的改變菜的狀態:
1) 先是通過洗這個動作把菜變成干凈的菜,洗(菜)則得到干凈的菜;
2) 然后干凈的菜再通過切這個動作得到切好的菜,注意,這里干凈的菜是切這個動作的對象,而洗(菜)則是得到干凈的菜,換句話說是切這個動作的對象是洗(菜),所以這里的整體動作是切(洗(菜));
3) 然后切好的菜通過炒這個動作做成熟的菜,從而到這里的整體工作是炒(切(洗(菜)));
4) 最后吃的是炒好的菜,整體的動作是吃(炒(切(洗(菜))))。
於是代碼就是
吃(炒(切(洗(菜))))
以上的代碼和過程式編程有很大差別,它突出的是把對象通過動作不斷的變換,而這里的動詞其實就是函數。所以這種類型的編程叫函數式編程。
邏輯式編程
邏輯式編程是從另外一個思路去編程。它強調的是我們事先知道一系列事實,然后通過這些事實自動推出合理的結果。
代碼可能長這樣:
洗干凈的菜 <- 洗(臟的菜)
切好的菜 <- 切(洗干凈的菜)
炒好的菜 <- 炒(切好的菜)
吃菜 <- 吃(炒好的菜)
? 吃菜 <- 臟的菜
以上就輸出吃菜的步驟,問號是我們具體需要查詢的目的,而其他的都是事先已經知道的事實,這些事實的排列順序無所謂。
看看這個像不像人的行為?人先學會一堆看起來彼此獨立的知識,然后用這些知識去自己解決遇到的問題,解決問題的過程實際上是人腦在已知的知識中不斷搜索。
所以這種編程范式用於早期的人工智能。
面向對象編程
面向對象編程並非是一個孤立的編程范式,它一般和以上幾種編程范式綁定在一起。我們最常見的面向對象編程通常主要基於過程式編程。
面向對象的思想是把處理抽象為數據、方法,再把數據、方法打包抽象為對象,在對象的基礎上提取共性抽象為類,這些則為封裝,再引入繼承、多態等性質來體現類與類之間的關系。
炒菜整體圍繞着菜來,那么我們可以將圍繞菜的一切看成一個對象,用面向對象描述,可能如下:
菜.洗()
菜.切()
菜.炒()
菜.吃()
面向對象+函數式
面向對象也會經常和函數式結合在一起,明確了程序中的數據對象,而函數則是對象的方法,而對象方法的調用流體現了對象的轉換。
菜.洗().切().炒().吃()
上述每個方法的調用都會返回一個新的對象,從而又可以使用方法。這種方始的編程目前很流行。
回到計算機
計算機很多東西實際是來源於生活,但是大多時候,我們在生活中的很多經驗是表達的不夠規范的。而計算機中我們要學習的實際上是把這些經驗形式化、規范化,引入更加抽象化的元素,比如數學,以便反復應用乃至推廣。
上面列舉的各種編程范式,思維的重心彼此都有明顯差異,我們學習不同的范式實際上也是為了不同角度的看待問題,以求思路更加寬廣。