一、開閉原則(Open Closed Principle,OCP)
含義
開閉原則的含義是:當應用的需求改變時,在不修改軟體物體的源代碼或者二進制代碼的前提下,可以擴展模塊的功能,使其滿足新的需求,
作用
開閉原則是面向物件程式設計的終極目標,它使軟體物體擁有一定的適應性和靈活性的同時具備穩定性和延續性,具體來說,其作用如下:
◆ 對軟體測驗的影響:軟體遵守開閉原則的話,軟體測驗時只需要對擴展的代碼進行測驗就可以了,因為原有的測驗代碼仍然能夠正常運行,
◆ 可以提高代碼的可復用性:粒度越小,被復用的可能性就越大;在面向物件的程式設計中,根據原子和抽象編程可以提高代碼的可復用性,
◆ 可以提高軟體的可維護性:遵守開閉原則的軟體,其穩定性高和延續性強,從而易于擴展和維護,
實作方式
可以通過“抽象約束、封裝變化”來實作開閉原則,即通過介面或者抽象類為軟體物體定義一個相對穩定的抽象層,而將相同的可變因素封裝在相同的具體實作類中,
因為抽象靈活性好,適應性廣,只要抽象的合理,可以基本保持軟體架構的穩定,而軟體中易變的細節可以從抽象派生來的實作類來進行擴展,當軟體需要發生變化時,只需要根據需求重新派生一個實作類來擴展就可以了,
二、里氏替換原則(Liskov Substitution Principle,LSP)
含義
繼承必須確保超類所擁有的性質在子類中仍然成立,
里氏替換原則主要闡述了有關繼承的一些原則,也就是什么時候應該使用繼承,什么時候不應該使用繼承,以及其中蘊含的原理,里氏替換原是繼承復用的基礎,它反映了基類與子類之間的關系,是對開閉原則的補充,是對實作抽象化的具體步驟的規范,
作用
◆ 里氏替換原則是實作開閉原則的重要方式之一,
◆ 它克服了繼承中重寫父類造成的可復用性變差的缺點,
◆ 它是動作正確性的保證,即類的擴展不會給已有的系統引入新的錯誤,降低了代碼出錯的可能性,
實作方式
里氏替換原則通俗來講就是:子類可以擴展父類的功能,但不能改變父類原有的功能,也就是說:子類繼承父類時,除添加新的方法完成新增功能外,盡量不要重寫父類的方法,
如果通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的可復用性會比較差,特別是運用多型比較頻繁時,程式運行出錯的概率會非常大,
如果程式違背了里氏替換原則,則繼承類的物件在基類出現的地方會出現運行錯誤,這時其修正方法是:取消原來的繼承關系,重新設計它們之間的關系,
三、依賴倒置原則(Dependence Inversion Principle,DIP)
含義
依賴倒置原則的原始定義為:高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象;抽象不應該依賴細節,細節應該依賴抽象,其核心思想是:要面向介面編程,不要面向實作編程,
依賴倒置原則是實作開閉原則的重要途徑之一,它降低了客戶與實作模塊之間的耦合,
作用
◆ 依賴倒置原則可以降低類間的耦合性,
◆ 依賴倒置原則可以提高系統的穩定性,
◆ 依賴倒置原則可以減少并行開發引起的風險,
◆ 依賴倒置原則可以提高代碼的可讀性和可維護性,
實作方式
依賴倒置原則的目的是通過要面向介面的編程來降低類間的耦合性,所以我們在實際編程中只要遵循以下4點,就能在專案中滿足這個規則:
◆ 每個類盡量提供介面或抽象類,或者兩者都具備,
◆ 變數的宣告型別盡量是介面或者是抽象類,
◆ 任何類都不應該從具體類派生,
◆ 使用繼承時盡量遵循里氏替換原則,
四、單一職責原則(Single Responsibility Principle,SRP)
含義
單一職責原則規定一個類應該有且僅有一個引起它變化的原因,否則類應該被拆分,
優點
單一職責原則的核心就是控制類的粒度大小、將物件解耦、提高其內聚性,如果遵循單一職責原則將有以下優點:
◆ 降低類的復雜度,一個類只負責一項職責,其邏輯肯定要比負責多項職責簡單得多,
◆ 提高類的可讀性,復雜性降低,自然其可讀性會提高,
◆ 提高系統的可維護性,可讀性提高,那自然更容易維護了,
◆ 變更引起的風險降低,變更是必然的,如果單一職責原則遵守得好,當修改一個功能時,可以顯著降低對其他功能的影響,
實作方式
單一職責原則是最簡單但又最難運用的原則,需要設計人員發現類的不同職責并將其分離,再封裝到不同的類或模塊中,而發現類的多重職責需要設計人員具有較強的分析設計能力和相關重構經驗,
五、介面隔離原則(Interface Segregation Principle,ISP)
含義
以上兩個定義的含義是:要為各個類建立它們需要的專用介面,而不要試圖去建立一個很龐大的介面供所有依賴它的類去呼叫,
優點
介面隔離原則是為了約束介面、降低類對介面的依賴性,遵循介面隔離原則有以下5個優點:
◆ 將臃腫龐大的介面分解為多個粒度小的介面,可以預防外來變更的擴散,提高系統的靈活性和可維護性,
◆ 介面隔離提高了系統的內聚性,減少了對外互動,降低了系統的耦合性,
◆ 如果介面的粒度大小定義合理,能夠保證系統的穩定性;但是,如果定義過小,則會造成介面數量過多,使設計復雜化;如果定義太大,靈活性降低,無法提供定制服務,給整體專案帶來無法預料的風險,
◆ 使用多個專門的介面還能夠體現物件的層次,因為可以通過介面的繼承,實作對總介面的定義,
◆ 能減少專案工程中的代碼冗余,過大的大介面里面通常放置許多不用的方法,當實作這個介面的時候,被迫設計冗余的代碼,
實作方式
在具體應用介面隔離原則時,應該根據以下幾個規則來衡量:
◆ 介面盡量小,但是要有限度,一個介面只服務于一個子模塊或業務邏輯,
◆ 為依賴介面的類定制服務,只提供呼叫者需要的方法,屏蔽不需要的方法,
◆ 了解環境,拒絕盲從,每個專案或產品都有選定的環境因素,環境不同,介面拆分的標準就不同深入了解業務邏輯,
◆ 提高內聚,減少對外互動,使介面用最少的方法去完成最多的事情,
六、迪米特法則(Law of Demeter,LoD)
含義
迪米特法則的定義是:只與你的直接朋友交談,不跟“陌生人”說話,其含義是:如果兩個軟體物體無須直接通信,那么就不應當發生直接的相互呼叫,可以通過第三方轉發該呼叫,其目的是降低類之間的耦合度,提高模塊的相對獨立性,
迪米特法則中的“朋友”是指:當前物件本身、當前物件的成員物件、當前物件所創建的物件、當前物件的方法引數等,這些物件同當前物件存在關聯、聚合或組合關系,可以直接訪問這些物件的方法,
優點
迪米特法則要求限制軟體物體之間通信的寬度和深度,正確使用迪米特法則將有以下兩個優點:
◆ 降低了類之間的耦合度,提高了模塊的相對獨立性,
◆ 由于親合度降低,從而提高了類的可復用率和系統的擴展性,
但是,過度使用迪米特法則會使系統產生大量的中介類,從而增加系統的復雜性,使模塊之間的通信效率降低,所以,在釆用迪米特法則時需要反復權衡,確保高內聚和低耦合的同時,保證系統的結構清晰,
實作方式
從迪米特法則的定義和特點可知,它強調以下2點:
◆ 從依賴者的角度來說,只依賴應該依賴的物件,
◆ 從被依賴者的角度說,只暴露應該暴露的方法,
所以,在運用迪米特法則時要注意以下6點:
◆ 在類的劃分上,應該創建弱耦合的類,類與類之間的耦合越弱,就越有利于實作可復用的目標,
◆ 在類的結構設計上,盡量降低類成員的訪問權限,
◆ 在類的設計上,優先考慮將一個類設定成不變類,
◆ 在對其他類的參考上,將參考其他物件的次數降到最低,
◆ 不暴露類的屬性成員,而應該提供相應的訪問器(set方法和get 方法),
◆ 謹慎使用序列化(Serializable)功能,
七、合成復用原則(Composite Reuse Principle,CRP)
含義
它要求在軟體復用時,要盡量先使用組合或者聚合等關聯關系來實作,其次才考慮使用繼承關系來實作,
作用
通常類的復用分為繼承復用和合成復用兩種,繼承復用雖然有簡單和易實作的優點,但它也存在以下缺點:
◆ 繼承復用破壞了類的封裝性,因為繼承會將父類的實作細節暴露給子類,父類對子類是透明的,所以這種復用又稱為“白箱”復用,
◆ 子類與父類的耦合度高,父類的實作的任何改變都會導致子類的實作發生變化,這不利于類的擴展與維護,
◆ 它限制了復用的靈活性,從父類繼承而來的實作是靜態的,在編譯時已經定義,所以在運行時不可能發生變化,
采用組合或聚合復用時,可以將已有物件納入新物件中,使之成為新物件的一部分,新物件可以呼叫已有物件的功能,它有以下優點:
◆ 它維持了類的封裝性,因為成分物件的內部細節是新物件看不見的,所以這種復用又稱為“黑箱”復用,
◆ 新舊類之間的耦合度低,這種復用所需的依賴較少,新物件存取成分物件的唯一方法是通過成分物件的介面,
◆ 復用的靈活性高,這種復用可以在運行時動態進行,新物件可以動態地參考與成分物件型別相同的物件,
實作方式
合成復用原則是通過將已有的物件納入新物件中,作為新物件的成員物件來實作的,新物件可以呼叫已有物件的功能,從而達到復用,
總結
這7種設計原則是軟體設計模式必須盡量遵循的原則,各種原則要求的側重點不同:
◆ 開閉原則是總綱,它告訴我們要對擴展開放,對修改關閉,
◆ 里氏替換原則告訴我們不要破壞繼承體系,
◆ 依賴倒置原則告訴我們要面向介面編程,
◆ 單一職責原則告訴我們實作類要職責單一,
◆ 介面隔離原則告訴我們在設計介面的時候要精簡單一,
◆ 迪米特法則告訴我們要降低耦合度,
◆ 合成復用原則告訴我們要優先使用組合或者聚合關系復用,少用繼承關系復用,
2021年最新Java面試題(帶答案)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/262182.html
標籤:其他
上一篇:服務熔斷與限流:Sentinel
