很多開發者在面對設計/架構時,常常有想學但無從下手,學了又不會用的困擾。學習設計并不是只學習設計模式,在進行設計時,我們需要底層思想來支持,這里的底層思想其實就是設計原則,而設計原則則是面向對象編程基于現實背景衍生出來的一套規則,用來解決開發中的痛點。
一個好的架構需要反復進行思考以及設計。
一、面向對象
什么是面向對象? 先來看下基本定義:
面向對象是一種風格,會以類作為代碼的基本單位,通過對象訪問,并擁有封裝、繼承、多態、抽象四種特性作為基石,可讓其更為智能。代表語言Java。
1. 四大特性(也有人說三種,不要糾結)
(1) 封裝
封裝也被稱為信息隱藏。類通過暴露有限的訪問接口,授權外部僅能通過類提供的方式(或者叫函數)來訪問內部信息或者數據。
將用戶信息隱藏在內部,在確實需要訪問時,再通過暴露出來的唯一入口進行,這一過程就是封裝,合理運用封裝可以降低模塊間依賴關系(松耦合)。
?。?) 繼承
“繼承”是面向對象中的第二特征,體現了類與類之間的“is-a”關系。當兩個類進行繼承關聯綁定的時候,子類自動具備來自于父類的屬性和行為。可以提升復用性解決模板代碼問題,提升開發效率的同時也解決了錯寫,漏寫帶來的問題。
(3) 多態
一句話概括“多態”:一個對象有多種形態。
合理運用多態可以寫出易擴展的代碼,基于接口而非實現編程和開閉原則的核心
?。?) 抽象
抽象的目的是為了隱藏方法的具體實現,讓調用者只需要關心方法提供了哪些方法(功能),并不需要知道這些功能是如何實現的。在Java中體現方式是接口和抽象類
(5) 接口和抽象類的區別
接口更側重于功能的設計,并且能將具體實現與調用者隔離,一般要以接口隔離原則設計接口及粒度越細越好
抽象類更側重于提升復用性,在原有的基礎上預留擴展點供開發者靈活實現
區別:接口可以降低模塊間耦合性,抽象類可提升復用性。
相同點:均有較好的擴展性,符合開閉原則
2. 誕生背景
談及面向對象必定離不開面向過程,畢竟它就是由面向過程衍變而來,吸收其大部分優點并解決其痛點。那什么是面向過程呢?基本定義如下:
分析出解決問題所需要的步驟,然后用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就可以了,更側重于功能的設計。代表語言C
面向對象在編程之前需要基于四大特性對功能做建模設計,可以提高代碼安全性、復用性、擴展性,更易于維護。既然面向對象這么智能為什么面向過程語言還沒有被淘汰?其實面向對象語言的智能是針對我們開發者的,為了能讓我們能寫出易于維護的代碼會多做一步設計,雖然離開發者更近了 但離機器卻遠了,畢竟機器只認識0和1而已。C語言規則簡單易于形成機器碼,所以執行效率高,這也是其沒有被淘汰的原因。
二、六大設計原則才是一切設計的基石
設計原則是基于面向對象思想衍變出來的一些規則,用來解決實際開發中的一些痛點,是所有設計的底層思想,也是我個人認為是設計/架構領域最重要的知識,所以請大家務必掌握好
?。?) 單一設計原則
單一原則很好理解,指一個函數或者一個類再或者一個模塊,職責越單一復用性就越強,同時能夠間接降低耦合性。
?。?) 開閉原則
一句話概括開閉原則:對擴展開放,修改關閉。它即充分詮釋抽象、多態特性,又是多數行為型設計模式的基礎,遍布于各大優秀框架之中,是最重要的一條設計原則,僅這一條原則就能把你的設計能力提高40%
(3) 迪米特法則
基本概念:不該有直接依賴關系的模塊不要有依賴。有依賴關系的模塊之間,盡量只依賴必要的接口。迪米特法則很好理解并且非常實用,它和單一設計原則很像,前者符合松耦合后者符合高內聚。
?。?) 接口隔離原則
基本概念:接口的調用者不應該依賴它不需要的接口。乍一看與迪米特法則很相似。接口隔離原則與迪米特法則目的很相似,都可以降低模塊間依賴關系。但接口隔離更側重于設計單一接口,提升復用性并間接降低模塊間依賴關系,而迪米特法則是直接降低模塊間依賴關系。
?。?) 里氏替換原則
基本概念:
設計子類的時候,要遵守父類的行為約定。父類定義了函數的行為約定,子類可以改變函數的內部實現邏輯,但不能改變函數原有的行為約定。
里氏替換非常簡單并且很容易遵守,在使用繼承時,允許復寫父類方法,但不要改變其功能。比如自定義View,子類的onMeasure中一定要調用setMeasureaDimission()方法(或者直接使用super),否則會影響父類方法功能(會拋異常),也既違背了里氏替換原則。
?。?) 依賴倒置原則
控制反轉: 提及依賴倒置便不得不提控制反轉,一句話概括:將復雜的程序操作控制權由程序員交給成熟的框架處理,程序員-》成熟的框架為反轉,框架應暴露出擴展點由程序員實現。
什么是依賴倒置?
高層模塊(使用者)不應依賴低層模塊(被使用者),它們共同依賴同一個抽象,抽象不要依賴具體實現細節,具體實現細節依賴抽象。
其實核心點就是基于接口而非實現編程,高層模塊(業務層)不依賴于低層模塊(SQLiteDao/RoomDao),而是依賴于抽象(IDao),可見依賴倒置也是開閉原則擴展而來。 區別是依賴倒置更側重于指導框架的設計,框架層應該盡量將更多的細節隱藏在內部,對外只暴露抽象(抽象類/接口),指導框架設計這方面核心就是控制反轉。
責編AJX
評論
查看更多