設計模式(二):面向對象與面向過程的區別與聯繫
面向對象與面向過程
在前面我們講述了面向對象的概念,在這裡我們再分析一些另一種編程範式:面向過程。
面向過程和面向過程語言
針對面向對象的概念解釋,這裡,我們用相同的方式來對面向過程進行解釋:
- 面向過程是一種編程範式,其重點是將函數作為程式碼組織的基本單元,其將數據和方法相分離,通過函數的順序執行來完成任務;
- 面向過程語言對應的就是不支援類和對象的定義,也不支援面向對象的一些特性,如封裝、多態等。
優劣
從上面的定義看出,面向過程的優劣勢如下所示:
- 在流程比較複雜的時候,面向過程會變得吃力,因為流程複雜,因此可能會創建出許多函數和組織結構,但因為沒有類和對象的概念,只能程式設計師手動組織程式碼來進行維護,因此會無處下手,很繁瑣;
- 面向對象風格的程式碼更易復用、易拓展、易維護:
- 易復用:通過繼承的方式來複用程式碼;
- 易拓展:通過多態可以直接用父類指針來調用新的子類實現邏輯,而不需要再進行更改,通過抽象,我們不需要知道方法的具體實現,這樣實現改變了,也不用改程式碼;
- 易維護:通過封裝,因為外部可修改的渠道被限制,因此方便維護。
- 面向過程關注的是設計一組流程來讓機器來執行,會更加的死板;而面向對象關注的是對現實世界的建模,對真實業務的抽象;
- 但是簡單的實現邏輯,直接使用面向過程也可以,因為其更符合人完成一件事的思維習慣。
開發壞習慣
現在主流的程式語言基本都是面向對象的,可能我們也認為自己平常寫的程式碼肯定都是符合面向對象的定義的。
因此,現在就讓我們來看一下,平常我們的哪些壞習慣,讓我們不經意間寫出了面向過程的程式碼吧。
濫用getter、setter
在設計類的時候,不管三七二十一,直接為所有的屬性設置 getter/setter 方法。
這樣的設計方式,首先破壞了封裝的特性,會導致所有外部方可以直接修改類中的屬性欄位。
通過返回 getter 方法,如果返回的是一個對象,那麼即使類沒有提供 setter 方法,也可以直接進行更改,大家想一下,這種情況,該如何避免呢?
濫用全局變數和全局方法
在編程過程中,可能會用到一些常量類和工具類,在編程中,就會將所有的常量全部放到一個類中,或將工具類的方法全部設計靜態的。
針對常量類來說,不推薦將所有的常量全部放到一個類中,首先這樣的程式碼不易維護,太亂,其次,如果只需要裡面的一兩個常量而已,也會增加整體項目的編譯時間。
因此針對常量來說,一種方式是將相關的常量分門別類的放到不同的類中,或者如果就只有一個類需要該常量的話,就不要再設計一個第三方類了,直接放到對應類需要用的地方,
再說工具類,其實工具類的設計是純面向過程的,因為裡面全都是 static 方法,也即以函數作為組織程式碼的基本單元,但該設計是十分有必要且合理的,因為有一些方法其的確在項目中,不屬於任何一個類,但是又有很多類需要用到。因此在實際編寫中,工具類就盡量採用分門別類的方式,這樣會更加榮易維護一些。
定義數據和方法分離的類
該說法第一次聽過可能會有點懵,什麼叫數據和方法分離的類。其實我們大家看一下現在自己寫的類就懂了。
我們寫的程式碼裡面是不是有很多 VO、DTO 等實體類,這些實體類裡面全都是一些屬性定義,而不包括方法的定義,相關的方式大多數都放在了 Service 層中以函數為形式組織在了一起。
其實,我們現在用的這種 MVC 的開發模式就是典型的面向過程開發風格,其是基於貧血模型的開發模式,不符合面向對象的定義。
相對應,就是基於充血模型的 DDD 開發模式,其設計的類是包含屬性和方法的,以類作為領域中的基本的實體,從而達到高內聚的作用。
公眾號截圖
文章在公眾號「iceWang」第一手更新,有興趣的朋友可以關注公眾號,第一時間看到筆者分享的各項知識點,謝謝!筆芯!