冒號(hào)課堂§4.3:匯總范式
冒號(hào)課堂
第四課 重溫范式(3)
4.3匯總范式——一張五味俱全的大烙餅
形者神之質(zhì),神者形之用 ——《范縝·神滅論》
關(guān)鍵詞: 編程范式,設(shè)計(jì)模式
摘要: 總結(jié)編程范式
?提問(wèn)
l 編程范式與設(shè)計(jì)模式有什么區(qū)別?
l 編程范式的核心價(jià)值是什么?
l 總結(jié)前面介紹的編程范式,它們各自有哪些代表語(yǔ)言?核心概念和運(yùn)行機(jī)制是什么?針對(duì)的問(wèn)題和主要的目的是什么?實(shí)現(xiàn)原理是什么?常見(jiàn)的應(yīng)用有哪些?有什么不足之處?
:講解
稍事休整后,大家重新團(tuán)結(jié)在以冒號(hào)為中心的周?chē)?/span>
問(wèn)號(hào)再度發(fā)問(wèn):“編程范式與設(shè)計(jì)模式都是一種抽象的軟件思想,都有一套具體的實(shí)現(xiàn)方法。單從字面上看,‘編程’與‘設(shè)計(jì)’、‘范式’與‘模式’的區(qū)別似乎也不太大。它們究竟有什么不同呢?”
“這個(gè)問(wèn)題有點(diǎn)意思。”冒號(hào)頷言,“設(shè)計(jì)模式一般針對(duì)某一特定場(chǎng)景的問(wèn)題,而編程范式針對(duì)的是廣泛得多的問(wèn)題領(lǐng)域,通常有一整套的思想和理論體系,具有全局性、系統(tǒng)性和滲透性,這一點(diǎn)在五大重要范式中顯得尤為突出。因此,編程范式更普適更抽象,涉及的深度和廣度也是設(shè)計(jì)模式難以比擬的。”
引號(hào)不免有些疑問(wèn):“但事件驅(qū)動(dòng)式不是也能作為設(shè)計(jì)模式嗎?”
冒號(hào)解疑:“這倒并不矛盾。同樣的思想用在整體系統(tǒng)的結(jié)構(gòu)設(shè)計(jì)上,則稱(chēng)為架構(gòu)模式;用在局部模塊的細(xì)節(jié)實(shí)現(xiàn)上,則稱(chēng)為設(shè)計(jì)模式[1];用在引導(dǎo)編程實(shí)踐上,則稱(chēng)為編程范式。”
句號(hào)的武俠癮又犯了:“設(shè)計(jì)模式好比組合套路,能在一些特定場(chǎng)合下克敵制勝;編程范式則好比武功門(mén)派,博大精深且自成體系。”
“很形象的比喻。”冒號(hào)贊賞道,“設(shè)計(jì)模式是遵循設(shè)計(jì)原則的一些具體技巧,以保證代碼的靈活性、擴(kuò)展性和可重用性為目的。它重在設(shè)計(jì),對(duì)語(yǔ)言一般沒(méi)有要求[2]。編程范式則不同,對(duì)語(yǔ)言往往有專(zhuān)門(mén)的要求。通常所說(shuō)的某某范式的語(yǔ)言,即指該語(yǔ)言對(duì)該范式在語(yǔ)法上有明確充分的支持,不需要借助其他的范式或工具。事實(shí)上,語(yǔ)言本來(lái)就是圍繞其所倡導(dǎo)的核心范式來(lái)設(shè)計(jì)的[3]。”
逗號(hào)詢(xún)問(wèn):“如果一種語(yǔ)言不支持某種范式,那么還能用這種范式編程嗎?”
“語(yǔ)言不直接支持范式,只是說(shuō)明它不屬于該范式的語(yǔ)言,但還是可能求助工具來(lái)應(yīng)用該范式。比如元編程可以借助Yacc或ANTLR來(lái)完成,AOP可以借助一些庫(kù)或框架來(lái)實(shí)現(xiàn)。”冒號(hào)道,“正是依靠語(yǔ)言和工具的支持,編程范式得以建立起一套獨(dú)特而完善的抽象機(jī)制和方法體系,從而為所倡導(dǎo)的世界觀與方法論奠定基石。”
嘆號(hào)請(qǐng)求:“能不能幫我們理清一下思路,把學(xué)過(guò)的范式一并匯總比較?”
不一會(huì)兒,眾人面前呈現(xiàn)出一張表格,地毯似的覆蓋了整個(gè)投影屏——
編程范式 |
核心概念 |
關(guān)鍵突破 |
主要目的 |
代表語(yǔ)言 |
運(yùn)行機(jī)制 |
實(shí)現(xiàn)原理 |
常見(jiàn)應(yīng)用 |
命令式/過(guò)程式 (Imperative/Procedural) |
命令/過(guò)程 (Command /Procedure) |
突破單一主程序和非結(jié)構(gòu)化程序的限制 |
模擬機(jī)器思維,實(shí)現(xiàn)自頂向下的模塊設(shè)計(jì) |
Fortran/Pascal/C |
命令執(zhí)行 |
引入邏輯控制和子程序 |
交互式、事件驅(qū)動(dòng)型系統(tǒng);數(shù)值計(jì)算等 |
函數(shù)式/應(yīng)用式 (Functional/Applicative) |
函數(shù) (Function) |
突破機(jī)器思維的限制 |
模擬數(shù)學(xué)思維,簡(jiǎn)化代碼 |
Scheme/Haskell |
表達(dá)式計(jì)算 |
引入高階函數(shù),將函數(shù)作為數(shù)據(jù)處理 |
微積分計(jì)算;數(shù)學(xué)邏輯;博弈等 |
邏輯式 (Logic) |
斷言 (Predicate) |
突破邏輯與控制粘合的限制 |
專(zhuān)注邏輯分析,減少控制代碼 |
Prolog/Mercury |
邏輯推理 |
利用推理引擎在已知的事實(shí)和規(guī)則的基礎(chǔ)上進(jìn)行邏輯推斷 |
機(jī)器證明;專(zhuān)家系統(tǒng);自然語(yǔ)言處理;語(yǔ)義網(wǎng)(semantic web);決策分析;業(yè)務(wù)規(guī)則管理等 |
對(duì)象式 (Object-Oriented) |
對(duì)象 (Object) |
突破數(shù)據(jù)與代碼分離的限制 |
迎合人類(lèi)認(rèn)知模式,提高軟件的易用性和重用性 |
Smalltalk/Java
|
對(duì)象間信息交換 |
引入封裝、繼承和多態(tài)機(jī)制 |
大型復(fù)雜交互式系統(tǒng)等 |
并發(fā)式/并行式 (Concurrent/Parallel) |
進(jìn)程/線程 (Process/Thread) |
突破串行的限制 |
充分利用資源、提高運(yùn)行效率、提高軟件的響應(yīng)能力 |
Erlang/Oz
|
進(jìn)程/線程間通訊與同步 |
引入并行的線程模塊以及模塊間的通訊與同步機(jī)制 |
圖形用戶(hù)界面;I/O處理;多任務(wù)系統(tǒng)如操作系統(tǒng)、網(wǎng)絡(luò)服務(wù)器等;實(shí)時(shí)系統(tǒng);嵌入式系統(tǒng);計(jì)算密集型系統(tǒng)如科學(xué)計(jì)算、人工智能等 |
泛型式 (Generic) |
算法 (Algorithm) |
突破靜態(tài)類(lèi)型語(yǔ)言的限制 |
提高算法的普適性 |
Ada/Eiffel/C++
|
算法實(shí)例化 (多發(fā)生于編譯期) |
利用模板推遲類(lèi)型指定 |
普適性算法如排序、搜索等;集合類(lèi)容器等 |
元編程 (Metaprogramming) |
元程序 (Metaprogram) |
突破語(yǔ)言的常規(guī)語(yǔ)法限制 |
減少手工編碼,提升語(yǔ)言級(jí)別 |
Lisp/Ruby/JavaScript |
動(dòng)態(tài)生成代碼或自動(dòng)修改執(zhí)行指令 |
利用代碼生成或語(yǔ)言?xún)?nèi)建的反射(reflection)、動(dòng)態(tài)等機(jī)制,將程序語(yǔ)言作為數(shù)據(jù)來(lái)處理 |
自動(dòng)代碼生成;定義結(jié)構(gòu)化配置文件;IDE;編譯器;解釋器;人工智能;模型驅(qū)動(dòng)架構(gòu)(MDA);領(lǐng)域特定語(yǔ)言(DSL)等 |
切面式 (Aspect-Oriented) |
切面 (Aspect) |
突破橫切關(guān)注點(diǎn)無(wú)法模塊化的限制 |
實(shí)現(xiàn)橫切關(guān)注點(diǎn)分離 |
AspectJ/AspectC++
|
在接入點(diǎn)處執(zhí)行建議 |
通過(guò)編織(weaving)將附加行為嵌入主體程序 |
日志輸出;代碼跟蹤;性能監(jiān)控;異常處理;安全檢查;事務(wù)管理等 |
事件驅(qū)動(dòng) (Event-Driven) |
事件 (Event) |
突破順序、同步的流程限制 |
調(diào)用者與被調(diào)用者在代碼和時(shí)間上雙重解耦 |
C#/VB.NET |
監(jiān)聽(tīng)器收到事件通知后做出響應(yīng) |
引入控制反轉(zhuǎn)和異步機(jī)制 |
圖形用戶(hù)界面;網(wǎng)絡(luò)應(yīng)用;服務(wù)器;操作系統(tǒng);IoC框架;異步輸入;DOM等 |
嘆號(hào)怔了怔,好似被一張巨大的烙餅給噎住了。
冒號(hào)并不急于講解,欲以靜制動(dòng)。
果然,逗號(hào)沉不住氣了,問(wèn)道:“在第一欄的編程范式及其代表語(yǔ)言中,為什么并發(fā)式的代表語(yǔ)言沒(méi)有Java和C#,只有Erlang和Oz?”
“Java和C#雖然在語(yǔ)法和核心庫(kù)中為并發(fā)編程提供了不少支持,但真正將并發(fā)范式融入基本設(shè)計(jì)理念的語(yǔ)言還得數(shù)Erlang、Oz這些較為冷門(mén)的語(yǔ)言。”冒號(hào)解釋?zhuān)?#8220;類(lèi)似地,比起Java、JavaScript等語(yǔ)言來(lái),C#和VB.NET在語(yǔ)言設(shè)計(jì)上對(duì)事件驅(qū)動(dòng)式編程給予了更多的關(guān)注[4],因而更具代表性。”
問(wèn)號(hào)發(fā)現(xiàn):“第三欄‘關(guān)鍵突破’的提法很特別啊。”
冒號(hào)輕捶桌面以示強(qiáng)調(diào):“一種編程范式之所以能獨(dú)樹(shù)一幟,關(guān)鍵在于它突破了原有的編程方式的某些限制,帶來(lái)革命性的新思維和新方法,進(jìn)一步解放程序員的勞動(dòng)力。這便是范式的核心價(jià)值所在。”
引號(hào)如獲至寶:“這張表格濃縮了范式的精華,既是對(duì)此前知識(shí)的總結(jié),也是對(duì)今后編程的指導(dǎo),實(shí)在太有用了!”
句號(hào)顯得更為冷靜:“有其長(zhǎng)必有其短。我們了解了每種范式的長(zhǎng)處,是不是還應(yīng)該了解它們各自的短處?”
冒號(hào)開(kāi)始對(duì)各個(gè)范式逐一數(shù)落:“過(guò)程式編程的數(shù)據(jù)與代碼脫節(jié),不方便維護(hù);函數(shù)式和邏輯式的開(kāi)發(fā)效率一般比過(guò)程式高,但運(yùn)行效率和語(yǔ)言表現(xiàn)力則有所不如;對(duì)象式編程用于數(shù)學(xué)計(jì)算、符號(hào)處理等對(duì)象特征淡薄的領(lǐng)域,在心理上缺乏認(rèn)知基礎(chǔ),在運(yùn)行效率上不如純過(guò)程式,在開(kāi)發(fā)效率上不如函數(shù)式;并發(fā)式編程增加了代碼的復(fù)雜度,加重了程序員的負(fù)擔(dān);泛型式編程影響了代碼的可讀性,過(guò)度使用模塊還可能造成代碼膨脹(code bloat)[5];元編程過(guò)于強(qiáng)大,運(yùn)用不當(dāng)會(huì)超出程序員的控制,宜謹(jǐn)慎使用;切面式編程減少了程序的可預(yù)測(cè)性和可控性,同時(shí)給代碼的跟蹤調(diào)試帶來(lái)一定困難,還可能造成性能上的損失;事件驅(qū)動(dòng)式編程雖然也能用于同步的流程應(yīng)用,但畢竟機(jī)制更復(fù)雜,沒(méi)有普通的流程式編程那么自然易懂。”
嘆號(hào)看上去有點(diǎn)泄氣:“您可真夠絕的,先把這些編程范式一個(gè)個(gè)捧到天上,又幾桿子它們一個(gè)個(gè)打下云端。”
“因其長(zhǎng)而容己,因其短而容他,此萬(wàn)物之理也。”冒號(hào)忽然惜言如金,一番之乎者也地予以回應(yīng)。
句號(hào)借用了一句俗話:“不怕有缺點(diǎn),就怕沒(méi)特點(diǎn)。”
冒號(hào)本欲多言,卻恐眾人食多傷胃,遂作結(jié)案陳詞:“盡管只是管中窺豹,相信大家多少見(jiàn)識(shí)了編程范式的魅力之處。它們各擅勝場(chǎng),有風(fēng)格之別而無(wú)高下之分。作文繪畫(huà)講究形神兼?zhèn)洌幊桃膊焕狻?strong>語(yǔ)言為形,范式為神。若能以神導(dǎo)形、以形傳神,則看似平白無(wú)趣的程序也能寫(xiě)出詩(shī)畫(huà)般的意境。”
一席話說(shuō)得眾人皆覺(jué)雖不能至,然心向往之。
,插語(yǔ)
[1] 因此設(shè)計(jì)模式有時(shí)被稱(chēng)為微架構(gòu)(microarchitecture)模式。
[2] 雖然設(shè)計(jì)模式一般多用于OOP語(yǔ)言,但并不總是必須的,更何況大多流行語(yǔ)言均支持OOP。
[3] 當(dāng)然隨著語(yǔ)言的演進(jìn),也可能支持新的范式。如Java的generics是后來(lái)加入語(yǔ)言以支持泛型編程的。
[4] C#和VB.NET專(zhuān)門(mén)為事件驅(qū)動(dòng)式設(shè)計(jì)了event、delegate等關(guān)鍵字以及一些配套的便利機(jī)制。
[5] 這里的代碼不是指程序員寫(xiě)的源代碼,而是指編譯器生成的代碼。
。總結(jié)
l 相比設(shè)計(jì)模式,編程范式針對(duì)的問(wèn)題領(lǐng)域更廣泛,提出的思想和方法更普適、更抽象、更系統(tǒng)。此外,設(shè)計(jì)模式重在設(shè)計(jì),對(duì)語(yǔ)言和工具的要求不高,而編程范式需要建立一套抽象機(jī)制和方法體系,離不開(kāi)語(yǔ)言或工具的支持。
l 編程范式的核心價(jià)值在于:突破原有的編程方式的某些限制,帶來(lái)新思維和新方法,從而進(jìn)一步解放程序員的勞動(dòng)力。
l 正文中編程范式的匯總表格既是對(duì)此前知識(shí)的總結(jié),也是對(duì)今后編程的指導(dǎo)。
l 既要了解編程范式的長(zhǎng)處,也要了解它們的短處。
l 編程范式為神,編程語(yǔ)言為形,應(yīng)以神導(dǎo)形、以形傳神。
“”參考
[1] Elena Bolshakova.PROGRAMMING PARADIGMS IN COMPUTER SCIENCE EDUCATION.International Journal "Information Theories & Applications",2005,Vol.12:285-290
[2] Amnon H. Eden,Rick Kazman.Architecture, design, implementation.Proceedings of the 25th International Conference on Software engineering ,2003:149–159
posted on 2008-12-15 16:28 鄭暉 閱讀(2952) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 冒號(hào)課堂