通過(guò)封裝、繼承、多態(tài)把程序的耦合度降低,用設計模式使程序更加的靈活,容易修改,并且易于復用??s短開(kāi)發(fā)周期,重用性和繼承性高,降低了重復的工作量,但缺點(diǎn)是,程序的處理效率相對會(huì )降低。
面向對象三大特點(diǎn):
封裝,繼承,多態(tài);
其三個(gè)主要的目標是:
重用性、靈活性、擴展性。
面向對象的五大原則:
1、單一職責原則 ( Single Responsibility Principle )
2、開(kāi)閉原則 ( Open-Close Principle )
3、里氏替換原則 ( Liskov Substitution Principle)
4、接口隔離原則 (Interface Segregation Principle)
5、依賴(lài)倒置原則 (Dependence Inversion Principle)
單一職責原則 ( Single Responsibility Principle )
定義:就一個(gè)類(lèi)而言,應該僅有一個(gè)引起它的變化的原因。通俗的說(shuō),一個(gè)類(lèi)只負責一項職責。
原因:如果一個(gè)類(lèi)承擔的職責過(guò)多,就等于把這些職責耦合在一起,一個(gè)職責的變化可能會(huì )削弱或者抑制這個(gè)類(lèi)完成其他職責的能力,這種耦合會(huì )導致脆弱的設計,當變化發(fā)生時(shí),設計會(huì )遭受到意想不到的破壞。
例如,類(lèi)A擁有P1、P2兩項職責,當需求變更導致需要修改P1,就有可能讓原本正常的P2職責發(fā)生故障。
優(yōu)勢:
類(lèi)的復雜性降低,實(shí)現什么職責都有清晰明確的定義;
可讀性提高,復雜性降低,那當然可讀性提高了;
可維護性提高,可讀性提高,那當然更容易維護了;
變更引起的風(fēng)險降低,變更是必不可少的,如果接口的單一職責做得好,一個(gè)接口修改只對相應的實(shí)現類(lèi)有影響,對其他的接口無(wú)影響,這對系統的擴展性、維護性都有非常大的幫助。
開(kāi)閉原則 ( Open-Close Principle )
定義:軟件實(shí)體應當對擴展開(kāi)放,對修改關(guān)閉。通俗說(shuō),軟件實(shí)體(類(lèi),模塊、函數等等)應該可以擴展,但是不可修改。
原因:在軟件的生命周期內,因為變化、升級和維護等原因需要對軟件原有代碼進(jìn)行修改時(shí),可能會(huì )給舊代碼中引入錯誤。
總結:當軟件需要變化時(shí),我們應該盡量通過(guò)擴展的方式來(lái)實(shí)現變化,而不是通過(guò)修改已有的代碼來(lái)實(shí)現。
里氏替換原則 ( Liskov Substitution Principle)
定義:任何基類(lèi)可以出現的地方,子類(lèi)一定可以出現。通俗的說(shuō),一個(gè)軟件實(shí)體如果使用的是一個(gè)父類(lèi),那么一定適用于其子類(lèi),而且它察覺(jué)不出父類(lèi)對象和子類(lèi)對象的區別。也就是說(shuō),子類(lèi)能夠替換父類(lèi)被使用。
原因:需要在子類(lèi)B拓展一個(gè)F2方法,方法F2需要用到父類(lèi)A已實(shí)現的F1方法,假如在類(lèi)B將F1方法重寫(xiě),可能會(huì )導致F2方法沒(méi)達到預期的結果。
因此:
子類(lèi)可以實(shí)現父類(lèi)的抽象方法,但不能覆蓋父類(lèi)的非抽象方法。
子類(lèi)中可以增加自己特有的方法。
當子類(lèi)的方法重載父類(lèi)的方法時(shí),方法的前置條件(即方法的形參)要比父類(lèi)方法的輸入參數更寬松。
當子類(lèi)的方法實(shí)現父類(lèi)的抽象方法時(shí),方法的后置條件(即方法的返回值)要比父類(lèi)更嚴格。
子類(lèi)盡量不要去重寫(xiě)父類(lèi)已實(shí)現的方法,子類(lèi)可以去實(shí)現父類(lèi)里沒(méi)有實(shí)現的方法
接口隔離原則 (Interface Segregation Principle)
定義:客戶(hù)端不應該依賴(lài)它不需要的接口;一個(gè)類(lèi)對另一個(gè)類(lèi)的依賴(lài)應該建立在最小的接口上。
原因,接口I1有3個(gè)方法聲明F1、F2、F3,但是類(lèi)A只需要實(shí)現F1、F2,為了保證程序正常編譯,不得不去實(shí)現一個(gè)不做任何業(yè)務(wù)的F3方法。這樣就導致接口臃腫,沉余代碼過(guò)多。
因此,盡量細化接口,我們要為各個(gè)類(lèi)建立專(zhuān)用的接口,而不要試圖去建立一個(gè)很龐大的接口供所有依賴(lài)它的類(lèi)去調用。
采用接口隔離原則對接口進(jìn)行約束時(shí),要注意以下幾點(diǎn):
接口盡量小,但是要有限度。但是如果過(guò)小,則會(huì )造成接口數量過(guò)多,使設計復雜化。
為依賴(lài)接口的類(lèi)定制服務(wù),只暴露給調用的類(lèi)它需要的方法,它不需要的方法則隱藏起來(lái)。只有專(zhuān)注地為一個(gè)模塊提供定制服務(wù),才能建立最小的依賴(lài)關(guān)系。
提高內聚,減少對外交互。使接口用最少的方法去完成最多的事情。
依賴(lài)倒置原則 (Dependence Inversion Principle)
定義:高層模塊不應該依賴(lài)低層模塊,二者都應該依賴(lài)其抽象;抽象不應該依賴(lài)細節;細節應該依賴(lài)抽象。抽象可以解釋為抽象類(lèi)和接口,細節解釋為實(shí)現類(lèi)。
原因:假如有類(lèi)A原本是依賴(lài)類(lèi)B,現在有需求改動(dòng),需要改為對類(lèi)C的依賴(lài),那么我們就得對類(lèi)A進(jìn)行調整,因此,我們對類(lèi)A改動(dòng)的時(shí)候,會(huì )對原有程序帶來(lái)意外的風(fēng)險。
因此,將類(lèi)B、C相同的行為抽象為接口I1,而類(lèi)A依賴(lài)成I1,那么類(lèi)A可以通過(guò)接口I1間接與類(lèi)B、C進(jìn)行關(guān)聯(lián)。從而減少對類(lèi)A的修改,以后需求修改只要添加類(lèi)D、E對接口I1的實(shí)現即可,降低類(lèi)A與其他低層類(lèi)之間的耦合,形成了面向接口編程,同時(shí)也滿(mǎn)足了開(kāi)閉原則。
傳遞依賴(lài)關(guān)系有三種方式:
接口傳遞、構造方法傳遞、setter方法傳遞
另外,
低層模塊盡量都要有抽象類(lèi)或接口,或者兩者都有。
變量的聲明類(lèi)型盡量是抽象類(lèi)或接口。
使用繼承時(shí)遵循里氏替換原則。
聯(lián)系客服