由軟件構造引申的OOP與POP的心得體會

  在大一初學C語言的時候,所解決的問題都是一些輕量級的簡單問題,當時寫過一個教學管理系統。這個教學管理系統的功能很簡單,思想就是“流水線”:按部就班的實現所有流程。要完成整個教學管理系統,實際上就是完成一些函數,這些函數之間的邏輯組織結構就是人所認知的邏輯結構,要完成一個教學管理系統,首先要實現一些功能:比如 1.錄入學生信息 2.爲每個學生分配課程 3.爲每個學生分配老師 4.爲每個學生錄入成績 5.進行成績的統計。

  上面這個流程很直觀,而且實現起來也很流暢。我們只需要將這些函數進行實現就行了。但是在實際操作中,這樣POP的程序設計過程可能會遇到一些問題,比如某一年,有一些課程可以改由多名教師上課,學生分配的課程可以進行更改,學生可以進行分數複覈等等。但凡要實現這些功能,就需要對原有軟件實現做出極大的改造,甚至是幾乎重寫。

  而衆所周知,現在軟件構造講究“敏捷開發”,什麼是敏捷開發呢?

敏捷開發以用戶的需求進化爲核心,採用迭代、循序漸進的方法進行軟件開發。在敏捷開發中,軟件項目在構建初期被切分成多個子項目,各個子項目的成果都經過測試,具備可視、可集成和可運行使用的特徵。換言之,就是把一個大項目分爲多個相互聯繫,但也可獨立運行的小項目,並分別完成,在此過程中軟件一直處於可使用狀態。

  如果我們僅僅是爲了完成課程作業的話,那我們基本用不到版本的更替迭代,問題是如果我們這樣做,那實際工程只能是一堆“屎山”,代碼幾乎無法維護。這不禁讓我想到此前的報道,美國的很多銀行系統使用的是幾十年前流行的語言,這種語言現在已經基本沒人用了,而且之前的代碼沒有現在“敏捷開發”的思想,當時的代碼組織結構極其笨重,雖然很穩定,但是難以修改。在幾十年後的今天當人們想要加以維護時,發現這件事難以登天,即使開出百萬年薪也找不到合適的人。這個例子也說明了軟件“易於更改性”的重要性,試想一下,如果所有軟件都只追求穩定性而不考慮可更改性,那每隔幾年就要進行“輪子重造”,不斷的造輪子,會讓程序員們苦不堪言。

  但是通過OOP的思想,我們就可以解決遠古的不具有“面向對象”特性語言的種種缺點。OOP和POP的本質區別在於:他們考慮的事情不同。

  POP是面向過程的編程思想,這種思想是“以過程爲本”的,類似於狀態轉移。我們要做一件事,首先要考慮的是要實現哪些步驟,就像上面的教學管理系統,每個步驟只有在上一個步驟完成之後才能進行實現。這是一個“流式”編程的概念,他模仿人們做事的流程,因此單元與單元之間的耦合度很高,只要有一個功能發生變化,可能就會導致其他的功能完全需要重構。

  而OOP則是面向對象的編程思想,這種思想是“以人爲本”的,我們將實現每個功能都劃歸給一些特定的對象,比如上面的教學管理系統,我們需要實現的對象可能包括:課程,教師資源,選課系統等等,我們考慮的不是事件與事件之間的耦合關係,我們恰恰是要減少模塊之間的關聯關係。這也是爲了我們進行後期維護而進行的設計,倘若模塊之前耦合度極高,那又會陷入面向過程編程的深坑。

  在引入OOP之後,我們就自然而然的可以感受到OOP的三大特徵:封裝性、繼承性和多態性。所謂封裝性,就是模塊與模塊之間是互不關聯的,也就是他們之間的耦合度比較低,我們可以把模塊當做磚頭,實現一個軟件就是完成一些磚塊的堆積。通過封裝讓開發app就像蓋房子一樣簡單,我們不需要自己造各種磚頭,甚至可以複用別人的磚頭。

  所謂繼承性,也是爲了簡化編程的複雜度,因爲自然界有很多的子類和父類的關係,或者說有些物品的所有特徵都存在於別的物品中。那我們只需要通過簡單的繼承,就可以使這些子類完全獲得父類可見的成員變量和方法,大大減低了代碼量。

  說到這裏,就不得不提一下Java特殊的繼承機制,在C++裏面是可以有多繼承的,即一個子類可以繼承多個父類。但是這樣的設計往往會導致代碼邏輯之間很混亂。在Java中取消了多繼承的功能,我們一般採用接口的多實現來完成C++裏面需要多繼承才能實現的功能。就像在我們HIT軟件構造課程所寫的三個app中,對於每個app都可以設定不同的接口組合,我們通過實現多個接口來完成這些功能的組合,顯得尤爲方便。

  最後就是多態性,這個特性存在的原因就是繼承,比如方法的多態-重寫,子類型多態-通過不同的實例化。

  上面就是一些OOP和POP的功能對比,較詳細的介紹了一些OOP的優點。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章