Android 之 OO Principle(面向對象的原則)

OO Principle(面向對象的原則)

OO 是什麼

一、OOP

① 面向對象(OO)

就是基於對象概念,以對象爲中心,以類和繼承爲構造機制,充分利用接口和多態提供靈活性,來認識、理解、刻劃客觀世界和設計、構建相應的軟件系統。面向對象的基本特徵:封裝、繼承、多態。

②OO設計原則(OOP)

概念性的,理想的最佳實踐,開放性的。方法論上是模糊的。

③OO設計模式(OODP)

解決具體問題的具體方法。實現了OOP。

考慮設計模式的最根本原因在於變化。包括modification和extension。最常說到的詞就是封裝變化和松耦合,重用和擴展,可維護性

二、耦合性

① 函數的松耦合:把某個具體的功能提取出來。

在多處可能都需要作同一件事情,而這一件事情未來可能需要修改或者擴展,這時候考慮用函數來封裝之。當有改變需要發生時,只需要函數改變即可,而不用每一處都更改,這是一種鬆散耦合。

②類的松耦合:繼承是強耦合,接口調用是松耦合。

繼承中派生類的實現要依賴於基類的實現,而基類又通過虛函數調用派生類的代碼。基類的內部實現必 然是強耦合的,派生類可以看到這種強耦合的實現,就不可避免的依賴於這種強耦合,因而帶來了派生類與基類之間的強耦合。而接口繼承則可以避免這一點,一個類從一個接口繼承,它僅僅能看到接口規範,只要接口規範滿足,內部如何實現其它類並不關心。
類的繼承比組合耦合性更強。

③架構的松耦合:MV*(例如MVC,MVP,MVVP)

OO 常用六大原則

OO的常用六大原則是指SRP、ISP、OCP、LSP、DIP、DRY。
OO的設計原則不僅僅這六種。
如果沒有變化,那麼使用OO原則都是冗餘的。

一、SRP(Single Responsibility Principle): 單一職責原則

系統中的每一個對象都應該只有一個單獨的職責,而所有對象所關注的就是自身職責的完成。
如果一個類承擔的職責過多,就等於把這些職責耦合在了一起。一個職責的變化就可能削弱或者抑制耦合。這種設計會導致脆弱的設計。當變化發生的時候,設計會遭到意想不到的破壞。
內聚Cohesion 其實是SRP原則的另外一個名字。
典型最常用的符合SRP的設計就是分層結構

二、ISP(Interface Segregation Principle):接口隔離原則

接口不是高內聚的,一個接口可以分成多組方法,那麼這個接口就需要使用ISP處理一下。
接口的劃分是由使用它的客戶程序決定的,客戶程序是分離的接口也應該是分離的。
一個接口中包含太多行爲時候,導致它們的客戶程序之間產生不正常的依賴關係,我們要做的就是分離接口,實現解耦。不應該強迫客戶程序依賴它們不需要的使用的方法。
應用了ISP之後,客戶程序看到的是多個內聚的接口。
SRP和ISP都強調內聚,前者是面對自我,後者面向客戶

三、OCP(Open-Close Principle) : 開閉原則

類應該對修改關閉,對擴展打開。
改動(新的功能)是通過增加代碼進行的(靈活性),而不是改動現有的代碼(穩定性);
OCP的應用限定在可能會發生的變化上,通過創建抽象來隔離以後發生的同類變化。把系統的所有可能的行爲抽象成一個抽象底層,這個抽象層要預見所有可能的擴展,從而使得在任何擴展情況下,系統的抽象層不需修改;同時由於可以從抽象層導出一個或多個新的具體類可改變系統的行爲,因此對於可變的部分,系統設計對擴展是開放的。OCP背後的機制就是抽象和多態
在設計的開始就羅列系統所有可能的行爲加入到抽象層是不可能的,也是不合算的;對所有的可變因素進行預計和封裝也不太現實,因此,開閉原則很難被完全實現,只能在某些模塊、某種程度上、某個限度內符合OCP的要求。OCP具有理想主義的色彩,是OOD 的終極目標。
變化一定會存在。對程序中每一個可能的變化都肆意的抽象不是一個好主意,正確的做法是開發人員僅僅對頻繁變化的部分做出抽象。拒絕不成熟的抽象和抽象本身一樣重要。面對可能的變化,添加新的實現類,優於接口中添加新方法,優於修改實現類,優於修改接口。OCP原則傳遞出來這樣一個思想:一旦你寫出來了可以工作的代碼,就要努力保證這段代碼一直可以工作。一旦我們的代碼質量到了一個水平,我們要盡最大努力保證代碼質量不回退。比如代碼添加了無數對特定數據的處理,特化的代碼越來越多,代碼意圖開始含混不清,開始退化。OCP是OOD的核心,如果這個原則有效應用,我們就可以獲更強的可維護性,可重用,靈活性,健壯性。

四、LSP(The Liskov Substitution Principle): 里氏替換原則

LSP解釋了什麼時候使用繼承:子類必須能夠替換基類。例如,正方形不能繼承長方形,正方形和長方形都繼承四邊形。
最好不要從具體類派生 。實體類會具有和特定實體相關的方法,這些方法在子類中可能不會有用。
使用契約式編程方法。DBC(Design by Contract)把類和其客戶之間的關係看作是一個正式的協議,明確各方的權利和義務。在父類裏定義好子類需要實現的功能,而子類只要實現這些功能即可。

五、DIP(Dependency Inversion Principle):依賴倒置原則

可以通過抽象方法多態,但是儘量不要重寫。
高層模塊不應該依賴於底層模塊,二者都應該依賴於抽象。抽象不應該依賴於細節,細節應該依賴於抽象。
什麼是高層模塊?V 高於 C, C高於M
由於對低層模塊的依賴,高層模塊無法在沒有底層模塊的上下文環境中獨立運行。高層模塊無法實現複用。
如果高層依賴於低層,高層和底層其實就在同一層。
這裏的倒置不僅僅是依賴關係的倒置也是接口所有權的倒置。應用了DIP我們會發現往往是客戶擁有抽象的接口,而服務者從這些抽象接口派生。這就是著名的Hollywood原則:“Don‘t call us, we’ll call you。”底層模塊實現了在高層模塊聲明並被高層模塊調用的接口。

六、DRY(Don’t Repeat Yourself Principle):不要自我重複原則

通過抽取公共部分放置在一個地方避免代碼重複.
DRY 很簡單,但卻是確保我們代碼容易維護和複用的關鍵。
避免重複代碼候是確保每一個需求和功能在你的系統中只實現一次,否則很難維護和複用
DRY 原則衍生出的要求:系統信息和行爲都放在一個單一的,明顯的位置。
DRY 原則衍生出的要求:如何對系統職能進行良好的分割,職責清晰的界限一定程度上保證了代碼的單一性。

OO 最佳實踐

①封裝變化

②面向接口編程而非實現

③優先使用組合而非繼承

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