技術 | 面向對象七大原則

一、面向對象設計七大原則

  1. 單一職責原則(Single Responsibility Principle)
    每一個類應該專注于做一件事情。

  2. 里氏替換原則(Liskov Substitution Principle)
    超類存在的地方,子類是可以替換的。

  3. 依賴倒置原則(Dependence Inversion Principle)
    實現盡量依賴抽象,不依賴具體實現。

  4. 接口隔離原則(Interface Segregation Principle)
    應當為客戶端提供盡可能小的單獨的接口,而不是提供大的總的接口。

  5. 迪米特法則(Law Of Demeter)
    又叫最少知識原則,一個軟件實體應當盡可能少的與其他實體發(fā)生相互作用。

  6. 開閉原則(Open Close Principle)
    面向擴展開放,面向修改關閉。

  7. 組合/聚合復用原則(Composite/Aggregate Reuse Principle CARP)
    盡量使用合成/聚合達到復用,盡量少用繼承。原則: 一個類中有另一個類的對象。

二、細則

1) 單一職責原則(Single Responsibility Principle)
  • 因為:
    可以降低類的復雜度,一個類只負責一項職責,其邏輯肯定要比負責多項職責簡單的多;提高類的可讀性,提高系統(tǒng)的可維護性;變更引起的風險降低,變更是必然的,如果單一職責原則遵守的好,當修改一個功能時,可以顯著降低對其他功能的影響。需要說明的一點是單一職責原則不只是面向對象編程思想所特有的,只要是模塊化的程序設計,都適用單一職責原則。
  • 所以:
    從大局上看Android中的Paint和Canvas等類都遵守單一職責原則,Paint和Canvas各司其職。
2)里氏替換原則(Liskov Substitution Principle)
  • 因為:
    里氏替換原則告訴我們,在軟件中將一個基類對象替換成它的子類對象,程序將不會產生任何錯誤和異常,反過來則不成立,如果一個軟件實體使用的是一個子類對象的話,那么它不一定能夠使用基類對象。里氏替換原則是實現開閉原則的重要方式之一,由于使用基類對象的地方都可以使用子類對象,因此在程序中盡量使用基類類型來對對象進行定義,而在運行時再確定其子類類型,用子類對象來替換父類對象。
  • 所以:
    使用里氏替換原則時需要注意,子類的所有方法必須在父類中聲明,或子類必須實現父類中聲明的所有方法。盡量把父類設計為抽象類或者接口,讓子類繼承父類或實現父接口,并實現在父類中聲明的方法,運行時,子類實例替換父類實例,我們可以很方便地擴展系統(tǒng)的功能,同時無須修改原有子類的代碼,增加新的功能可以通過增加一個新的子類來實現。

從大局看Java的多態(tài)就屬于這個原則。

3)依賴倒置原則(Dependence Inversion Principle)
  • 因為:
    具體依賴抽象,上層依賴下層。假設B是較A低的模塊,但B需要使用到A的功能,這個時候,B不應當直接使用A中的具體類;而應當由B定義一抽象接口,并由A來實現這個抽象接口,B只使用這個抽象接口;這樣就達到了依賴倒置的目的,B也解除了對A的依賴,反過來是A依賴于B定義的抽象接口。通過上層模塊難以避免依賴下層模塊,假如B也直接依賴A的實現,那么就可能造成循環(huán)依賴。
  • 所以:
    采用依賴倒置原則可以減少類間的耦合性,提高系統(tǒng)的穩(wěn)定性,減少并行開發(fā)引起的風險,提高代碼的可讀性和可維護性。

從大局看Java的多態(tài)就屬于這個原則。

4)接口隔離原則(Interface Segregation Principle)
  • 因為:
    提供盡可能小的單獨接口,而不要提供大的總接口。暴露行為讓后面的實現類知道的越少越好。譬如類ProgramMonkey通過接口CodeInterface依賴類CodeC,類ProgramMaster通過接口CodeInterface依賴類CodeAndroid,如果接口CodeInterface對于類ProgramMonkey和類CodeC來說不是最小接口,則類CodeC和類CodeAndroid必須去實現他們不需要的方法。將臃腫的接口CodeInterface拆分為獨立的幾個接口,類ProgramMonkey和類ProgramMaster分別與他們需要的接口建立依賴關系。也就是采用接口隔離原則。
  • 所以:
    建立單一接口,不要建立龐大的接口,盡量細化接口,接口中的方法盡量少。也就是要為各個類建立專用的接口,而不要試圖去建立一個很龐大的接口供所有依賴它的類去調用。依賴幾個專用的接口要比依賴一個綜合的接口更靈活。接口是設計時對外部設定的約定,通過分散定義多個接口,可以預防外來變更的擴散,提高系統(tǒng)的靈活性和可維護性。

從大局來說Java的接口可以實現多繼承就是接口隔離原則的基礎保障。

5)迪米特法則(Law Of Demeter)
  • 因為:
    類與類之間的關系越密切,耦合度也就越來越大,只有盡量降低類與類之間的耦合才符合設計模式;對于被依賴的類來說,無論邏輯多復雜都要盡量封裝在類的內部;每個對象都會與其他對象有耦合關系,我們稱出現成員變量、方法參數、方法返回值中的類為直接的耦合依賴,而出現在局部變量中的類則不是直接耦合依賴,也就是說,不是直接耦合依賴的類最好不要作為局部變量的形式出現在類的內部。
  • 所以:
    一個對象對另一個對象知道的越少越好,即一個軟件實體應當盡可能少的與其他實體發(fā)生相互作用,在一個類里能少用多少其他類就少用多少,尤其是局部變量的依賴類,能省略盡量省略。同時如果兩個類不必彼此直接通信,那么這兩個類就不應當發(fā)生直接的相互作用。如果其中一個類需要調用另一個類的某一方法的話,可以通過第三者轉發(fā)這個調用。

從大局來說Android App開發(fā)中的多Fragment與依賴的Activity間交互通信遵守了這一法則。

6)開閉原則(Open Close Principle)
  • 因為:
    開放封閉原則主要體現在對擴展開放、對修改封閉,意味著有新的需求或變化時,可以對現有代碼進行擴展,以適應新的情況。軟件需求總是變化的,世界上沒有一個軟件的是不變的,因此對軟件設計人員來說,必須在不需要對原有系統(tǒng)進行修改的情況下,實現靈活的系統(tǒng)擴展。
  • 所以:
    可以通過Template Method模式和Strategy模式進行重構,實現對修改封閉,對擴展開放的設計思路。
    封裝變化,是實現開放封閉原則的重要手段,對于經常發(fā)生變化的狀態(tài),一般將其封裝為一個抽象,拒絕濫用抽象,只將經常變化的部分進行抽象。
7)組合/聚合復用原則(Composite/Aggregate Reuse Principle CARP)
  • 因為:
    其實整個設計模式就是在講如何類與類之間的組合/聚合。在一個新的對象里面通過關聯關系(包括組合關系和聚合關系)使用一些已有的對象,使之成為新對象的一部分,新對象通過委派調用已有對象的方法達到復用其已有功能的目的。也就是,要盡量使用類的合成復用,盡量不要使用繼承。
    如果為了復用,便使用繼承的方式將兩個不相干的類聯系在一起,違反里氏代換原則,哪是生搬硬套,忽略了繼承了缺點。繼承復用破壞數據封裝性,將基類的實現細節(jié)全部暴露給了派生類,基類的內部細節(jié)常常對派生類是透明的,白箱復用;雖然簡單,但不安全,不能在程序的運行過程中隨便改變;基類的實現發(fā)生了改變,派生類的實現也不得不改變;從基類繼承而來的派生類是靜態(tài)的,不可能在運行時間內發(fā)生改變,因此沒有足夠的靈活性。
  • 所以:
    組合/聚合復用原則可以使系統(tǒng)更加靈活,類與類之間的耦合度降低,一個類的變化對其他類造成的影響相對較少,因此一般首選使用組合/聚合來實現復用;其次才考慮繼承,在使用繼承時,需要嚴格遵循里氏代換原則,有效使用繼承會有助于對問題的理解,降低復雜度,而濫用繼承反而會增加系統(tǒng)構建和維護的難度以及系統(tǒng)的復雜度,因此需要慎重使用繼承復用。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容