編程范式,程序員的編程世界觀
編程范式,程序員的編程世界觀
編程范式(Programming Paradigm)是某種編程語言典型的編程風格或者說是編程方式。隨著編程方法學和軟件工程研究的深入,特別是OO思想的普及,范式 (Paradigm)以及編程范式等術語漸漸出現在人們面前。面向對象編程(OOP)常常被譽為是一種革命性的思想,正因為它不同于其他的各種編程范式。 編程范式也許是學習任何一門編程語言時要理解的最重要的術語。
托馬斯.庫恩提出“科學的革命”的范式論之后,Robert Floyd在1979年圖靈獎的頒獎演說中使用了編程范式一詞。編程范式一般包括三個方面,以OOP為例:
- 學科的邏輯體系——規則范式:如類/對象、繼承、動態綁定、方法改寫、對象替換等等機制。
- 心理認知因素——心理范式:按照面向對象編程之父Alan Kay的觀點,“計算就是模擬”。OO范式極其重視隱喻(metaphor)的價值,通過擬人化,按照自然的方式模擬自然。
- 自然觀/世界觀——觀念范式:強調程序的組織技術,視程序為松散耦合的對象/類的集合,以繼承機制將類組織成一個層次結構,把程序運行視為相互服務的對象們之間的對話。
簡單的說,編程范式是程序員看待程序應該具有的觀點。
為了進一步加深對編程范式的認識,這里介紹幾種最常見的編程范式。
需要再次提醒注意的是:編程范式是編程語言的一種分類方式,它并不針對某種編程語言。就編程語言而言,一種編程語言也可以適用多種編程范式。
過程化(命令式)編程
過程化編程,也被稱為命令式編程,應該是最原始的、也是我們最熟悉的一種傳統的編程方式。從本質上講,它是“馮.諾伊曼機“運行機制的抽象,它的編程思維方式源于計算機指令的順序排列。
(也就是說:過程化語言模擬的是計算機機器的系統結構,而并不是基于語言的使用者的個人能力和傾向。這一點我們應該都很清楚,比如:我們最早曾經使用過的單片機的匯編語言。)
過程化編程的步驟是:
首先,我們必須將待解問題的解決方案抽象為一系列概念化的步驟。然后通過編程的方式將這些步驟轉化為程序指令集(算法),而這些指令按照一定的順序 排列,用來說明如何執行一個任務或解決一個問題。這就意味著,程序員必須要知道程序要完成什么,并且告訴計算機如何來進行所需的計算工作,包括每個細節操 作。簡言之,就是將計算機看作一個善始善終服從命令的裝置。
所以在過程化編程中,把待解問題規范化、抽象為某種算法是解決問題的關鍵步驟。
其次,才是編寫具體算法和完成相應的算法實現問題的正確解決。當然,程序員對待解問題的抽象能力也是非常重要的因素,但這本身已經與編程語言無關了。
程序流程圖是過程化語言進行程序編寫的有效輔助手段。
盡管現存的計算機編程語言很多,但是人們把所有支持過程化編程范式的編程語言都被歸納為過程化編程語言。例如機器語言、匯編語言、BASIC、COBOL、C 、FORTRAN、語言等等許多第三代編程語言都被歸納為過程化語言。
過程化語言特別適合解決線性(或者說按部就班)的算法問題。它強調“自上而下(自頂向下)”“精益求精”的設計方式。這種方式非常類似我們的工作和生活方式,因為我們的日常活動都是按部就班的順序進行的。
過程化語言趨向于開發運行較快且對系統資源利用率較高的程序。過程化語言非常的靈活并強大,同時有許多經典應用范例,這使得程序員可以用它來解決多種問題。
過程化語言的不足之處就是它不適合某些種類問題的解決,例如那些非結構化的具有復雜算法的問題。問題出現在,過程化語言必須對一個算法加以詳盡的說明,并且其中還要包括執行這些指令或語句的順序。實際上,給那些非結構化的具有復雜算法的問題給出詳盡的算法是極其困難的。
廣泛引起爭議和討論的地方是:無條件分支,或goto語句,它是大多數過程式編程語言的組成部分,反對者聲稱:goto語句可能被無限地濫用;它給 程序設計提供了制造混亂的機會。目前達成的共識是將它保留在大多數語言中,對于它所具有的危險性,應該通過程序設計的規定將其最小化。
事件驅動編程
其實,基于事件驅動的程序設計在圖形用戶界面(GUI)出現很久前就已經被應用于程序設計中,可是只有當圖形用戶界面廣泛流行時,它才逐漸形演變為一種廣泛使用的程序設計模式。
在過程式的程序設計中,代碼本身就給出了程序執行的順序,盡管執行順序可能會受到程序輸入數據的影響。
在事件驅動的程序設計中,程序中的許多部分可能在完全不可預料的時刻被執行。往往這些程序的執行是由用戶與正在執行的程序的互動激發所致。
- 事件。就是通知某個特定的事情已經發生(事件發生具有隨機性)。
- 事件與輪詢。輪詢的行為是不斷地觀察和判斷,是一種無休止的行為方式。而事件是靜靜地等待事情的發生。事實上,在Windows出現之前,采用鼠標輸入字符模式的PC應用程序必須進行串行輪詢,并以這種方式來查詢和響應不同的用戶操做。
- 事件處理器。是對事件做出響應時所執行的一段程序代碼。事件處理器使得程序能夠對于用戶的行為做出反映。
事件驅動常常用于用戶與程序的交互,通過圖形用戶接口(鼠標、鍵盤、觸摸板)進行交互式的互動。當然,也可以用于異常的處理和響應用戶自定義的事件等等。
事件的異常處理比用戶交互更復雜。
事件驅動不僅僅局限在GUI編程應用。但是實現事件驅動我們還需要考慮更多的實際問題,如:事件定義、事件觸發、事件轉化、事件合并、事件排隊、事件分派、事件處理、事件連帶等等。
其實,到目前為止,我們還沒有找到有關純事件驅動編程的語言和類似的開發環境。所有關于事件驅動的資料都是基于GUI事件的。
屬于事件驅動的編程語言有:VB、C#、Java(Java Swing的GUI)等。它們所涉及的事件絕大多數都是GUI事件。
面向對象編程
過程化范式要求程序員用按部就班的算法看待每個問題。很顯然,并不是每個問題都適合這種過程化的思維方式。這也就導致了其它程序設計范式出現,包括我們現在介紹的面向對象的程序設計范式。
面向對象的程序設計模式已經出現二十多年,經過這些年的發展,它的設計思想和設計模式已經穩定的進入編程語言的主流。來自TIOBE Programming Community2010年11月份編程語言排名的前三名Java、C、C++中,Java和C++都是面向對象的編程語言。
面向對象的程序設計包括了三個基本概念:封裝性、繼承性、多態性。面向對象的程序語言通過類、方法、對象和消息傳遞,來支持面向對象的程序設計范式。
- 對象
世間萬事萬物都是對象。
面向對象的程序設計的抽象機制是將待解問題抽象為面向對象的程序中的對象。利用封裝使每個對象都擁有個體的身份。程序便是成堆的對象,彼此通過消息的傳遞,請求其它對象 進行工作。
- 類
每個對象都是其類中的一個實體。
物以類聚——就是說明:類是相似對象的集合。類中的對象可以接受相同的消息。換句話說:類包含和描述了“具有共同特性(數據元素)和共同行為(功能)”的一組對象。
比如:蘋果、梨、橘子等等對象都屬于水果類。
- 封裝
封裝(有時也被稱為信息隱藏)就是把數據和行為結合在一個包中,并對對象的使用者隱藏數據的實現過程。信息隱藏是面向對象編程的基本原則,而封裝是實現這一原則的一種方 式。
封裝使對象呈現出“黑盒子”特性,這是對象再利用和實現可靠性的關鍵步驟。
- 接口
每個對象都有接口。接口不是類,而是對符合接口需求的類所作的一套規范。接口說明類應該做什么但不指定如何作的方法。一個類可以有一個或多個接口。
- 方法
方法決定了某個對象究竟能夠接受什么樣的消息。面向對象的設計有時也會簡單地歸納為“將消息發送給對象”。
- 繼承
繼承的思想就是允許在已存在類的基礎上構建新的類。一個子類能夠繼承父類的所有成員,包括屬性和方法。
繼承的主要作用:通過實現繼承完成代碼重用;通過接口繼承完成代碼被重用。繼承是一種規范的技巧,而不是一種實現的技巧。
- 多態
多態提供了“接口與實現分離”。多態不但能改善程序的組織架構及可讀性,更利于開發出“可擴充”的程序。
繼承是多態的基礎。多態是繼承的目的。
合理的運用基于類繼承的多態、基于接口繼承的多態和基于模版的多態,能增強程序的簡潔性、靈活性、可維護性、可重用性和可擴展性。
面向對象技術一方面借鑒了哲學、心理學、生物學的思考方式,另一方面,它是建立在其他編程技術之上的,是以前的編程思想的自然產物。
如果說結構化軟件設計是將函數式編程技術應用到命令式語言中進行程序設計,面向對象編程不過是將函數式模型應用到命令式程序中的另一途徑,此時,模 塊進步為對象,過程龜縮到class的成員方法中。OOP的很多技術——抽象數據類型、信息隱藏、接口與實現分離、對象生成功能、消息傳遞機制等等,很多 東西就是結構化軟件設計所擁有的、或者在其他編程語言中單獨出現。但只有在面向對象語言中,他們才共同出現,以一種獨特的合作方式互相協作、互相補充。