前言
c和c++的區別是什么?不可置否,最重要的就是c++的編程思想是面向對象,而c的編程思想是面向過程,這是它們的本質區別,如果你在使用c++編程時使用的還是面向過程的編程思想,那么還不如使用c,因為這樣的做法已經丟掉了c++的思想精髓。在學習一門語言時,最重要的是學習它的設計思想,因為語法都是大同小異的,很快便可以掌握。那么面向過程和面向對象編程的發展歷史如何,區別是什么,各自的優缺點是什么,且聽我一一道來。
一、“自頂向下,逐步求精”的面向過程程序設計
面向過程程序設計的思想即這樣的一種解決思路 - 提出問題,分析問題的處理流程,將大問題分解為小問題,如果小問題比較復雜,就繼續划分小問題為更小的問題,然后通過小模塊一一解決小問題,最后再根據整個業務流程將這些小問題串在一起(調用函數),這樣就達到了解決所有問題的目的,如下:
於是,這樣從問題出發,自頂向下、逐步求精的開發思想我們稱之為“面向過程程序設計思想”,因為它主要是解決問題中的一個個過程。這種思想也是最早的編程語言的思想,因為它比較符合我們解決問題的方法,其他語言比如早期的Fortran、JavaScript等都是如此。它的優點如下:
優點1:程序結構簡單 - 僅由三種基本結構組成
面向過程編程的思想在程序實現上只需要三種控制結構,即順序、選擇、循環。通過這三種基本結構,我們就可以解決任何問題,所以我們可以專注於程序邏輯的實現,不需要學習、記憶更多的控制結構。
優點2:分而治之,各個擊破
當我們在解決復雜問題時,通常采用的就是“分而治之”的策略,即把大問題分解為小問題,然后再各個擊破這些小問題,這樣整個大問題就得到了解決。所以,面向過程程序設計思想也是采用這種“分而治之”的策略,把較大的程序按照業務邏輯划分為多個子模塊,然后在分工逐個完成這些子模塊。最后按照業務流程把他們組織起來,最終使得整個問題得到解決。按照一定的原則,把大問題細分為小的問題然后“各個擊破”,符合人們思考問題的一般規律,其設計結構更易於理解,同時這種方法也易於人們掌握,通過分解問題,降低了問題的復雜度,使得程序易於實現和維護,另外,部分分解后的小問題(子模塊)可以重復使用,從而避免了重復開發,而多個子模塊也可以由多人分工協作完成,提高開發效率。
優點3:自頂向下,逐步求精
面向過程程序設計思想倡導的方法是“自頂向下,逐步求精”,即從宏觀角度考慮,按照功能或者業務邏輯划分程序的子模塊,定義程序的整體結構,然后再對各個子模塊逐步細化,最終分解到程序語句為止。這種方法可以使程序員全面考慮問題,使程序的邏輯關系清晰明了。它讓整個開發過程從原來的考慮 “怎么做” 變成考慮 “先做什么,再做什么”,流程就更加清晰了。
缺點:
但是,一件事物必定有優點也有缺點,面向過程的程序設計當然也躲不過這種規律,並且缺點的凸顯往往是在程序的復雜性越來越高時才會出現的,那么這種設計思想的缺點是什么呢?
在面向過程程序設計時,數據和操作往往是分離的,這就導致如果數據的結構發生了變化,那么操作數據的函數不得不重新改寫,這個代價是非常高的。並且,數據往往不具有封裝性,很多變量都會暴露在全局,加大了被任意修改的風險。另外,一旦涉及到模塊的重新划分,往往需要修改原來寫好的功能模塊。且這種數據和操作相互分離的特點使得一些模塊跟具體的應用環境結合緊密,舊有的程序模塊就很難在新的程序中得到復用。所以,這些固有的缺點使它越來越難以適應大型的軟件項目的開發。正是在這樣的歷史背景下,一些新的程序設計思想開始不斷涌現,而面向對象的程序設計思想就是最重要的一環。
二、萬般皆對象:面向對象程序設計
面向對象的程序設計(OOP)是面向過程程序設計的繼承和發展,它不僅汲取了后者的精華,而且以一種更加接近人類思維的方式來分析和解決問題:程序是對現實世界的抽象和描述,現實世界的基本單元是物體,與之對應的,程序中的基本單元是對象。
面向對象思想認為:現實世界是由對象組成的,無論大到一個國家還是小到一個原子,都是如此。並且對象都由兩部分組成 - 描述對象狀態或屬性的數據(變量)以及描述對象行為或者功能的方法(函數)。並且與面向過程不同,面向對象是將數據和操作數據的函數緊密結合,共同構成對象來更加精確地描述現實世界,這是面向過程和面向對象兩者最本質的區別。
之前提到面型過程的缺點,即面向過程中數據和操作是分離的,當問題規模比較小時,需求變化不大的時候,面向過程工作都做的很好。 但是,當問題的規模越來越大、越來越復雜時,面向過程就顯得力不從心了,即修改了某個結構體,就不得不修改與之相關的所有過程函數,而一個過程函數的修改,往往又會設計到其他數據結構,在規模比較小的時候容易解決,但是當系統規模越來越大時,特別是涉及到了多人協作開發,這就非常困難,這就是著名的軟件危機。 正是如此,面向對象的程序設計應運而生,它的主要特點是封裝、繼承和多態。封裝即將數據和操作封裝在一起,並避免了局部變量的暴露,而只提供接口;繼承可以在原來的基礎上很快的產生新的對象;多態是同一個方法調用,針對不同的對象有不同的反應,這方便了程序的設計。
如上所示,封裝、繼承、多態就是面向對象程序設計的三大基石。 它們是緊密相連、不可分割的。通過封裝,我們可以將現實世界中的數據和對數據進行操作的動作捆綁在一起形成類,然后再通過類定義對象,很好地實現了對現實世界事物的抽象和描述;通過繼承,可以在舊類型的基礎上快速派生得到新的類型,很好地實現了設計和代碼的復用;同時多態機制保證了在繼承的同時,還有機會對已有行為進行重新定義,滿足了不斷出現的新需求的需要。
正是因為面向對象思想的封裝、繼承、多態這三大特性,使得面向對象思想在程序設計中有着不可替代的優勢。
(1)容易設計和實現
面向對象思想強調的是從客觀存在的事物(對象)出發來認識問題和分析解決問題,因為這種方式更加符合我們認識事物的規律,所以大大降低了問題的理解難度,而面向對象思想所應用的封裝、繼承、多態都是符合人類日常的思維習慣的,所以使用面向對象思想設計的程序結構清晰、更容易設計和實現。
(2)復用設計和代碼,開發效率和系統質量都得到了提高
面向對象思想的繼承和多態,強調了程序設計和代碼的重用,這在設計新系統的時候,可以最大限度地重用已有的、經過大量實踐檢驗的設計和代碼,使得系統能夠滿足新的業務需求並具有較高的質量。同時,因為可以服用以前的設計和代碼,所以大大提高了開發效率。
(3)容易擴展
開發大型系統的時候,最擔心的即使需求的變更以及對系統進行擴展,利用面向對象思想的封裝、繼承和多態,可以設計出“高內聚、低耦合”的系統結構,可以讓系統更加靈活、更容易擴展,從而輕松應對系統的擴展需求,降低維護成本。
最佳實踐:高內聚,低耦合。 這是軟件工程中的一個概念,通常用來判斷一個軟件設計的好壞。所謂的高內聚是指一個軟件模塊是由相關性很強的代碼組成,只負責某單一任務,也就是常說的“單一責任原則”。而低耦合指的是在一個完整的系統中,模塊與系統之間,盡可能保持相互獨立,即每個模塊盡可能獨立完成特定的子功能,模塊與模塊之間的接口,盡可能的少而簡單。