面向對象的7大設計原則

設計原則

在面向對象的軟件系統(tǒng)設計中秕豫,可維護性硕并,可復用性是衡量一個軟件系統(tǒng)是否健壯的重要指標膊升。而可維護性和可復用性是可以遵從基本的準則來得以實現(xiàn)怎炊。而這些準則就是面向對象設計的基本原則。面向對象的設計原則一共有7種廓译,這些原則都是以前的軟件工程師在實踐中總結的基本原則评肆,經得起項目的考驗,時間的檢驗非区,這些原則也是設計模式的基礎瓜挽。每種原則都蘊含面向對象的思想,從而從不同的緯度去提高軟件結構的設計水平征绸。

1:單一指責原則(SRP:Simple Responsibility Principle)

一個類只負責一個功能領域的相應職責久橙。
在使用該原則來進行軟件設計的時候一定要注意,不要讓類的承擔過多的職能管怠,承擔的職能越多淆衷,功能模塊間的耦合性越強,維護成本也就越高排惨,而且這個類被復用的可能性就越小吭敢。我們要將不同類型的職責拆分開來,分別封裝到不同的類中暮芭,來實現(xiàn)職責的單一化鹿驼。

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

軟件實體對擴展開放欲低,對修改關閉。軟件實體應當在不修改源代碼的情況下對功能進行擴展畜晰。
在軟件開發(fā)中砾莱,我們不得不面臨一個問題,那就是軟件的需求會隨著時間的推移而不斷的變化凄鼻,這時候一個可擴展性強腊瑟,靈活度高的軟件系統(tǒng)就顯的十分必要了。要滿足這樣要求的系統(tǒng)块蚌,必須要具備一些基本特定闰非。如果一個軟件系統(tǒng)符合開閉原則,那么這個系統(tǒng)就可以很好的滿足擴展性峭范,靈活性的需求财松。
而在實現(xiàn)開閉原則的過程中。抽象化的設計是重中之重纱控,抽象化才是開閉原則的關鍵辆毡,在Java中我們可以利用接口或抽象類來構建一個抽象層,而將具體的實現(xiàn)行為移至實現(xiàn)層完成甜害。當需要修改系統(tǒng)的行為時舶掖,我們不需要修改抽象層,只需要新增新的具體類來實現(xiàn)新的業(yè)務邏輯就可以了尔店。這樣我們就可以在不修改源代碼的基礎上實現(xiàn)新的功能眨攘,滿足開閉原則的要求。

3:里氏代換原則(LSP:Liskov Substitution Principle)

所有引用基類對象的地方能夠透明地使用其子類的對象闹获。
如果對每一個類型為T1的對象o1期犬,都有類型為T2的對象o2,使得以T1定義的所有程序P在所有的對象o1都替換成o2時避诽,程序P的行為沒有變化龟虎,那么類型T2是類型T1的子類型。
換言之沙庐,一個軟件實體如果使用的是一個基類的話鲤妥,那么一定適用于其子類,而且它根本不能察覺出基類對象和子類對象的區(qū)別拱雏。
比如棉安,假設有兩個類,一個是Base類铸抑,另一個是Child類贡耽,并且Child類是Base的子類。那么一個方法如果可以接受一個基類對象b的話:method1(Base b)那么它必然可以接受一個子類的對象method1(Child c).

注意事項

  • 為了保證軟件系統(tǒng)的擴展性,子類要重寫父類中所有的方法蒲赂。若在子類中存在父類中沒有的特有方法阱冶,那么通過父類則無法調用該方法。
  • 在運用里氏代換原則時候滥嘴,父類盡量設計成接口或者抽象類木蹬,子類繼承父類或者父接口,實現(xiàn)父類中聲明的方法若皱,在運行時镊叁,子類實例替代父類實例。這樣就可以很方便的擴展系統(tǒng)的功能走触,
  • Java語言中晦譬,在編譯階段,Java編譯器會檢查一個程序是否符合里氏代換原則饺汹,這是一個與實現(xiàn)無關的蛔添、純語法意義上的檢查痰催,但Java編譯器的檢查是有局限的兜辞。

4:依賴倒轉原則(DIP:Dependence Inversion Principle)

抽象不應該依賴于細節(jié),細節(jié)應該依賴于抽象夸溶。換句話說逸吵,要針對接口編程,而不是針對實現(xiàn)編程缝裁。
根據(jù)依賴倒置原則扫皱,我們應當盡量使用抽象類或接口來定義成員變量,參數(shù)類型捷绑,返回值類型韩脑,不要使用具體的實現(xiàn)類來做這些事情,
為了保證依賴倒置原則的良好應用粹污,具體類應該只實現(xiàn)抽象層的方法段多,不要給出多余的方法,抽象類無法調用具體類中特有的方法壮吩。
在實現(xiàn)依賴倒轉原則時进苍,我們需要針對抽象層編程,而將具體類的對象通過依賴注入(DependencyInjection, DI)的方式注入到其他對象中鸭叙,依賴注入是指當一個對象要與其他對象發(fā)生依賴關系時觉啊,通過抽象來注入所依賴的對象。

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

使用多個專門的接口沈贝,而不使用單一的總接口杠人。客戶端不應該依賴那些不需要的接口。每一種接口應該承擔相對獨立的功能嗡善,不該干的不要干市俊,自己該干的就要干好。
其中的接口有兩層含義

  • 某個類型中所有的方法,是邏輯上的抽象滤奈。
    當把“接口”理解成一個類型所提供的所有方法特征的集合的時候摆昧,這就是一種邏輯上的概念,接口的劃分將直接帶來類型的劃分蜒程∩鹉悖可以把接口理解成角色,一個接口只能代表一個角色昭躺,每個角色都有它特定的一個接口忌锯,此時,這個原則可以叫做“角色隔離原則”领炫。
  • 具體指代某個編程編程語言偶垮,“接口”的定義。
    如果把“接口”理解成狹義的特定語言的接口帝洪,那么ISP表達的意思是指接口僅僅提供客戶端需要的行為似舵,客戶端不需要的行為則隱藏起來,應當為客戶端提供盡可能小的單獨的接口葱峡,而不要提供大的總接口砚哗。在面向對象編程語言中,實現(xiàn)一個接口就需要實現(xiàn)該接口中定義的所有方法砰奕,因此大的總接口使用起來不一定很方便蛛芥,為了使接口的職責單一,需要將大接口中的方法根據(jù)其職責不同分別放在不同的小接口中军援,以確保每個接口使用起來都較為方便仅淑,并都承擔某一單一角色。接口應該盡量細化胸哥,同時接口中的方法應該盡量少涯竟,每個接口中只包含一個客戶端(如子模塊或業(yè)務邏輯類)所需的方法即可,這種機制也稱為“定制服務”烘嘱,即為不同的客戶端提供寬窄不同的接口昆禽。

在使用接口隔離原則時,我們需要注意控制接口的粒度蝇庭,接口不能太小醉鳖,如果太小會導致系統(tǒng)中接口泛濫,不利于維護哮内;接口也不能太大盗棵,太大的接口將違背接口隔離原則壮韭,靈活性較差,使用起來很不方便纹因。一般而言喷屋,接口中僅包含為某一類用戶定制的方法即可,不應該強迫客戶依賴于那些它們不用的方法瞭恰。

6:合成復用原則(CRP:Composite Reuse Principle)

盡量使用對象組合屯曹,而不是繼承來達到復用的目的。
一個對象通過關聯(lián)關系來引入其他已有的對象惊畏,通過委派調用已有對象中的方法恶耽,來實現(xiàn)復用功能的目的。
通常來說颜启,如果兩個類之間是“Has-A”的關系應使用組合或聚合偷俭,如果是“Is-A”關系可使用繼承。"Is-A"是嚴格的分類學意義上的定義缰盏,意思是一個類是另一個類的"一種"涌萤;而"Has-A"則不同,它表示某一個角色具有某一項責任口猜。

7:迪米特法則(LoD:Law of Demeter)

一個軟件實體應當盡可能少地與其他實體發(fā)生相互作用负溪。
迪米特法則要求,當系統(tǒng)中的一個模塊發(fā)生變更時暮的,應該盡可能少的影響其他模塊笙以,那樣系統(tǒng)的擴展會比較容易。迪米特原則可以降低系統(tǒng)的耦合程度冻辩,使類與類之間保持一種松耦合的關系。
迪米特原則要求我們“不要跟陌生人交談拆祈,只跟熟人打交道”恨闪,以下條件就是我們需要打交道的熟人。

  • 當前對象this放坏。
  • 對象中方法的形式參數(shù)咙咽。
  • 對象中映入的成員對象。
  • 如果成員對象是集合淤年,那么集合中的元素也是我們的熟人钧敞。
  • 當前對象中創(chuàng)建的其他對象。

迪米特法則要求我們在設計系統(tǒng)時麸粮,應該盡量減少對象之間的交互溉苛,如果兩個對象之間不必彼此直接通信,那么這兩個對象就不應當發(fā)生任何直接的相互作用弄诲,如果其中的一個對象需要調用另一個對象的某一個方法的話吼句,可以通過第三者轉發(fā)這個調用。簡言之性湿,就是通過引入一個合理的第三者來降低現(xiàn)有對象之間的耦合度澳骤。
在將迪米特法則運用到系統(tǒng)設計中時,要注意下面的幾點:在類的劃分上滴肿,應當盡量創(chuàng)建松耦合的類,類之間的耦合度越低,就越有利于復用想许,一個處在松耦合中的類一旦被修改,不會對關聯(lián)的類造成太大波及断序;在類的結構設計上伸刃,每一個類都應當盡量降低其成員變量和成員函數(shù)的訪問權限;在類的設計上逢倍,只要有可能捧颅,一個類型應當設計成不變類;在對其他類的引用上较雕,一個對象對其他對象的引用應當降到最低碉哑。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市亮蒋,隨后出現(xiàn)的幾起案子扣典,更是在濱河造成了極大的恐慌,老刑警劉巖慎玖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贮尖,死亡現(xiàn)場離奇詭異,居然都是意外死亡趁怔,警方通過查閱死者的電腦和手機湿硝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來润努,“玉大人关斜,你說我怎么就攤上這事∑探剑” “怎么了痢畜?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鳍侣。 經常有香客問我丁稀,道長,這世上最難降的妖魔是什么倚聚? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任线衫,我火速辦了婚禮,結果婚禮上秉沼,老公的妹妹穿的比我還像新娘桶雀。我一直安慰自己矿酵,他們只是感情好,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布矗积。 她就那樣靜靜地躺著全肮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棘捣。 梳的紋絲不亂的頭發(fā)上辜腺,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音乍恐,去河邊找鬼评疗。 笑死,一個胖子當著我的面吹牛茵烈,可吹牛的內容都是我干的百匆。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼呜投,長吁一口氣:“原來是場噩夢啊……” “哼加匈!你這毒婦竟也來了?” 一聲冷哼從身側響起仑荐,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤雕拼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粘招,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啥寇,經...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年洒扎,在試婚紗的時候發(fā)現(xiàn)自己被綠了辑甜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡逊笆,死狀恐怖栈戳,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情难裆,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布镊掖,位于F島的核電站乃戈,受9級特大地震影響,放射性物質發(fā)生泄漏亩进。R本人自食惡果不足惜症虑,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望归薛。 院中可真熱鬧谍憔,春花似錦匪蝙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至苫昌,卻和暖如春颤绕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祟身。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工奥务, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人袜硫。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓氯葬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親婉陷。 傳聞我的和親對象是個殘疾皇子帚称,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內容