编程范式,程序员的编程世界观
編程范式(Programming Paradigm)是某種編程語(yǔ)言典型的編程風(fēng)格或者說(shuō)是編程方式。隨著編程方法學(xué)和軟件工程研究的深入,特別是OO思想的普及,范式(Paradigm)以及編程范式等術(shù)語(yǔ)漸漸出現(xiàn)在人們面前。面向?qū)ο缶幊?#xff08;OOP)常常被譽(yù)為是一種革命性的思想,正因?yàn)樗煌谄渌母鞣N編程范式。編程范式也許是學(xué)習(xí)任何一門(mén)編程語(yǔ)言時(shí)要理解的最重要的術(shù)語(yǔ)。
托馬斯.庫(kù)恩提出“科學(xué)的革命”的范式論之后,Robert Floyd在1979年圖靈獎(jiǎng)的頒獎(jiǎng)演說(shuō)中使用了編程范式一詞。編程范式一般包括三個(gè)方面,以O(shè)OP為例:
簡(jiǎn)單的說(shuō),編程范式是程序員看待程序應(yīng)該具有的觀點(diǎn)。
為了進(jìn)一步加深對(duì)編程范式的認(rèn)識(shí),這里介紹幾種最常見(jiàn)的編程范式。?
需要再次提醒注意的是:編程范式是編程語(yǔ)言的一種分類(lèi)方式,它并不針對(duì)某種編程語(yǔ)言。就編程語(yǔ)言而言,一種編程語(yǔ)言也可以適用多種編程范式。?
過(guò)程化(命令式)編程?
過(guò)程化編程,也被稱(chēng)為命令式編程,應(yīng)該是最原始的、也是我們最熟悉的一種傳統(tǒng)的編程方式。從本質(zhì)上講,它是“馮.諾伊曼機(jī)“運(yùn)行機(jī)制的抽象,它的編程思維方式源于計(jì)算機(jī)指令的順序排列。
(也就是說(shuō):過(guò)程化語(yǔ)言模擬的是計(jì)算機(jī)機(jī)器的系統(tǒng)結(jié)構(gòu),而并不是基于語(yǔ)言的使用者的個(gè)人能力和傾向。這一點(diǎn)我們應(yīng)該都很清楚,比如:我們最早曾經(jīng)使用過(guò)的單片機(jī)的匯編語(yǔ)言。)
過(guò)程化編程的步驟是:
首先,我們必須將待解問(wèn)題的解決方案抽象為一系列概念化的步驟。然后通過(guò)編程的方式將這些步驟轉(zhuǎn)化為程序指令集(算法),而這些指令按照一定的順序排列,用來(lái)說(shuō)明如何執(zhí)行一個(gè)任務(wù)或解決一個(gè)問(wèn)題。這就意味著,程序員必須要知道程序要完成什么,并且告訴計(jì)算機(jī)如何來(lái)進(jìn)行所需的計(jì)算工作,包括每個(gè)細(xì)節(jié)操作。簡(jiǎn)言之,就是將計(jì)算機(jī)看作一個(gè)善始善終服從命令的裝置。
所以在過(guò)程化編程中,把待解問(wèn)題規(guī)范化、抽象為某種算法是解決問(wèn)題的關(guān)鍵步驟。其次,才是編寫(xiě)具體算法和完成相應(yīng)的算法實(shí)現(xiàn)問(wèn)題的正確解決。當(dāng)然,程序員對(duì)待解問(wèn)題的抽象能力也是非常重要的因素,但這本身已經(jīng)與編程語(yǔ)言無(wú)關(guān)了。
?程序流程圖是過(guò)程化語(yǔ)言進(jìn)行程序編寫(xiě)的有效輔助手段。?
盡管現(xiàn)存的計(jì)算機(jī)編程語(yǔ)言很多,但是人們把所有支持過(guò)程化編程范式的編程語(yǔ)言都被歸納為過(guò)程化編程語(yǔ)言。例如機(jī)器語(yǔ)言、匯編語(yǔ)言、BASIC、COBOL、C 、FORTRAN、語(yǔ)言等等許多第三代編程語(yǔ)言都被歸納為過(guò)程化語(yǔ)言。?
過(guò)程化語(yǔ)言特別適合解決線性(或者說(shuō)按部就班)的算法問(wèn)題。它強(qiáng)調(diào)“自上而下(自頂向下)”“精益求精”的設(shè)計(jì)方式。這種方式非常類(lèi)似我們的工作和生活方式,因?yàn)槲覀兊娜粘;顒?dòng)都是按部就班的順序進(jìn)行的。?
?過(guò)程化語(yǔ)言趨向于開(kāi)發(fā)運(yùn)行較快且對(duì)系統(tǒng)資源利用率較高的程序。過(guò)程化語(yǔ)言非常的靈活并強(qiáng)大,同時(shí)有許多經(jīng)典應(yīng)用范例,這使得程序員可以用它來(lái)解決多種問(wèn)題。?
過(guò)程化語(yǔ)言的不足之處就是它不適合某些種類(lèi)問(wèn)題的解決,例如那些非結(jié)構(gòu)化的具有復(fù)雜算法的問(wèn)題。問(wèn)題出現(xiàn)在,過(guò)程化語(yǔ)言必須對(duì)一個(gè)算法加以詳盡的說(shuō)明,并且其中還要包括執(zhí)行這些指令或語(yǔ)句的順序。實(shí)際上,給那些非結(jié)構(gòu)化的具有復(fù)雜算法的問(wèn)題給出詳盡的算法是極其困難的。?
廣泛引起爭(zhēng)議和討論的地方是:無(wú)條件分支,或goto語(yǔ)句,它是大多數(shù)過(guò)程式編程語(yǔ)言的組成部分,反對(duì)者聲稱(chēng):goto語(yǔ)句可能被無(wú)限地濫用;它給程序設(shè)計(jì)提供了制造混 亂的機(jī)會(huì)。目前達(dá)成的共識(shí)是將它保留在大多數(shù)語(yǔ)言中,對(duì)于它所具有的危險(xiǎn)性,應(yīng)該通過(guò)程序設(shè)計(jì)的規(guī)定將其最小化。?
事件驅(qū)動(dòng)編程?
其實(shí),基于事件驅(qū)動(dòng)的程序設(shè)計(jì)在圖形用戶(hù)界面(GUI)出現(xiàn)很久前就已經(jīng)被應(yīng)用于程序設(shè)計(jì)中,可是只有當(dāng)圖形用戶(hù)界面廣泛流行時(shí),它才逐漸形演變?yōu)橐环N廣泛使用的程序設(shè)計(jì)模式。?
在過(guò)程式的程序設(shè)計(jì)中,代碼本身就給出了程序執(zhí)行的順序,盡管執(zhí)行順序可能會(huì)受到程序輸入數(shù)據(jù)的影響。
在事件驅(qū)動(dòng)的程序設(shè)計(jì)中,程序中的許多部分可能在完全不可預(yù)料的時(shí)刻被執(zhí)行。往往這些程序的執(zhí)行是由用戶(hù)與正在執(zhí)行的程序的互動(dòng)激發(fā)所致。?
- 事件。就是通知某個(gè)特定的事情已經(jīng)發(fā)生(事件發(fā)生具有隨機(jī)性)。?
- 事件與輪詢(xún)。輪詢(xún)的行為是不斷地觀察和判斷,是一種無(wú)休止的行為方式。而事件是靜靜地等待事情的發(fā)生。事實(shí)上,在Windows出現(xiàn)之前,采用鼠標(biāo)輸入字符模式的PC應(yīng)用程序必須進(jìn)行串行輪詢(xún),并以這種方式來(lái)查詢(xún)和響應(yīng)不同的用戶(hù)操做。?
- 事件處理器。是對(duì)事件做出響應(yīng)時(shí)所執(zhí)行的一段程序代碼。事件處理器使得程序能夠?qū)τ谟脩?hù)的行為做出反映。?
事件驅(qū)動(dòng)常常用于用戶(hù)與程序的交互,通過(guò)圖形用戶(hù)接口(鼠標(biāo)、鍵盤(pán)、觸摸板)進(jìn)行交互式的互動(dòng)。當(dāng)然,也可以用于異常的處理和響應(yīng)用戶(hù)自定義的事件等等。
事件的異常處理比用戶(hù)交互更復(fù)雜。?
事件驅(qū)動(dòng)不僅僅局限在GUI編程應(yīng)用。但是實(shí)現(xiàn)事件驅(qū)動(dòng)我們還需要考慮更多的實(shí)際問(wèn)題,如:事件定義、事件觸發(fā)、事件轉(zhuǎn)化、事件合并、事件排隊(duì)、事件分派、事件處理、事 件連帶等等。
其實(shí),到目前為止,我們還沒(méi)有找到有關(guān)純事件驅(qū)動(dòng)編程的語(yǔ)言和類(lèi)似的開(kāi)發(fā)環(huán)境。所有關(guān)于事件驅(qū)動(dòng)的資料都是基于GUI事件的。?
屬于事件驅(qū)動(dòng)的編程語(yǔ)言有:VB、C#、Java(Java Swing的GUI)等。它們所涉及的事件絕大多數(shù)都是GUI事件。?
面向?qū)ο缶幊?
過(guò)程化范式要求程序員用按部就班的算法看待每個(gè)問(wèn)題。很顯然,并不是每個(gè)問(wèn)題都適合這種過(guò)程化的思維方式。這也就導(dǎo)致了其它程序設(shè)計(jì)范式出現(xiàn),包括我們現(xiàn)在介紹的面向?qū)ο蟮某绦蛟O(shè)計(jì)范式。?
面向?qū)ο蟮某绦蛟O(shè)計(jì)模式已經(jīng)出現(xiàn)二十多年,經(jīng)過(guò)這些年的發(fā)展,它的設(shè)計(jì)思想和設(shè)計(jì)模式已經(jīng)穩(wěn)定的進(jìn)入編程語(yǔ)言的主流。來(lái)自TIOBE Programming Community2010年11月份編程語(yǔ)言排名的前三名Java、C、C++中,Java和C++都是面向?qū)ο蟮木幊陶Z(yǔ)言。?
面向?qū)ο蟮某绦蛟O(shè)計(jì)包括了三個(gè)基本概念:封裝性、繼承性、多態(tài)性。面向?qū)ο蟮某绦蛘Z(yǔ)言通過(guò)類(lèi)、方法、對(duì)象和消息傳遞,來(lái)支持面向?qū)ο蟮某绦蛟O(shè)計(jì)范式。?
1. 對(duì)象
世間萬(wàn)事萬(wàn)物都是對(duì)象。
面向?qū)ο蟮某绦蛟O(shè)計(jì)的抽象機(jī)制是將待解問(wèn)題抽象為面向?qū)ο蟮某绦蛑械膶?duì)象。利用封裝使每個(gè)對(duì)象都擁有個(gè)體的身份。程序便是成堆的對(duì)象,彼此通過(guò)消息的傳遞,請(qǐng)求其它對(duì)象 進(jìn)行工作。?
2. 類(lèi)
每個(gè)對(duì)象都是其類(lèi)中的一個(gè)實(shí)體。
物以類(lèi)聚——就是說(shuō)明:類(lèi)是相似對(duì)象的集合。類(lèi)中的對(duì)象可以接受相同的消息。換句話說(shuō):類(lèi)包含和描述了“具有共同特性(數(shù)據(jù)元素)和共同行為(功能)”的一組對(duì)象。
比如:蘋(píng)果、梨、橘子等等對(duì)象都屬于水果類(lèi)。?
3. 封裝
封裝(有時(shí)也被稱(chēng)為信息隱藏)就是把數(shù)據(jù)和行為結(jié)合在一個(gè)包中,并對(duì)對(duì)象的使用者隱藏?cái)?shù)據(jù)的實(shí)現(xiàn)過(guò)程。信息隱藏是面向?qū)ο缶幊痰幕驹瓌t,而封裝是實(shí)現(xiàn)這一原則的一種方 式。
封裝使對(duì)象呈現(xiàn)出“黑盒子”特性,這是對(duì)象再利用和實(shí)現(xiàn)可靠性的關(guān)鍵步驟。?
4. 接口
每個(gè)對(duì)象都有接口。接口不是類(lèi),而是對(duì)符合接口需求的類(lèi)所作的一套規(guī)范。接口說(shuō)明類(lèi)應(yīng)該做什么但不指定如何作的方法。一個(gè)類(lèi)可以有一個(gè)或多個(gè)接口。?
5. 方法
方法決定了某個(gè)對(duì)象究竟能夠接受什么樣的消息。面向?qū)ο蟮脑O(shè)計(jì)有時(shí)也會(huì)簡(jiǎn)單地歸納為“將消息發(fā)送給對(duì)象”。?
6. 繼承
繼承的思想就是允許在已存在類(lèi)的基礎(chǔ)上構(gòu)建新的類(lèi)。一個(gè)子類(lèi)能夠繼承父類(lèi)的所有成員,包括屬性和方法。
繼承的主要作用:通過(guò)實(shí)現(xiàn)繼承完成代碼重用;通過(guò)接口繼承完成代碼被重用。繼承是一種規(guī)范的技巧,而不是一種實(shí)現(xiàn)的技巧。?
7. 多態(tài)
多態(tài)提供了“接口與實(shí)現(xiàn)分離”。多態(tài)不但能改善程序的組織架構(gòu)及可讀性,更利于開(kāi)發(fā)出“可擴(kuò)充”的程序。
繼承是多態(tài)的基礎(chǔ)。多態(tài)是繼承的目的。
合理的運(yùn)用基于類(lèi)繼承的多態(tài)、基于接口繼承的多態(tài)和基于模版的多態(tài),能增強(qiáng)程序的簡(jiǎn)潔性、靈活性、可維護(hù)性、可重用性和可擴(kuò)展性。
面向?qū)ο蠹夹g(shù)一方面借鑒了哲學(xué)、心理學(xué)、生物學(xué)的思考方式,另一方面,它是建立在其他編程技術(shù)之上的,是以前的編程思想的自然產(chǎn)物。
如果說(shuō)結(jié)構(gòu)化軟件設(shè)計(jì)是將函數(shù)式編程技術(shù)應(yīng)用到命令式語(yǔ)言中進(jìn)行程序設(shè)計(jì),面向?qū)ο缶幊滩贿^(guò)是將函數(shù)式模型應(yīng)用到命令式程序中的另一途徑,此時(shí),模塊進(jìn)步為對(duì)象,過(guò)程龜縮到class的成員方法中。OOP的很多技術(shù)——抽象數(shù)據(jù)類(lèi)型、信息隱藏、接口與實(shí)現(xiàn)分離、對(duì)象生成功能、消息傳遞機(jī)制等等,很多東西就是結(jié)構(gòu)化軟件設(shè)計(jì)所擁有的、或者在其他編程語(yǔ)言中單獨(dú)出現(xiàn)。但只有在面向?qū)ο笳Z(yǔ)言中,他們才共同出現(xiàn),以一種獨(dú)特的合作方式互相協(xié)作、互相補(bǔ)充。
總結(jié)
以上是生活随笔為你收集整理的编程范式,程序员的编程世界观的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 小众编程语言同样值得你关注
- 下一篇: 大数据之hadoop伪集群搭建与MapR