開閉原則(open-closed principle, ocp)是指乙個軟體實體如類、模組和函式應該對擴充套件開放, 對修改關閉。強調的是用抽象構建框架,用實現擴充套件細節。可以提高軟體系統的可復用性及可維護性。開閉原則即是面向介面程式設計
開閉原則的實現方法
為了滿足開閉原則的對修改關閉原則以及擴充套件開放原則,應該對軟體系統中的不變的部分加以抽象,在物件導向的設計中,
可以把這些不變的部分加以抽象成不變的介面/父類,這些不變的介面可以應對未來的擴充套件;
介面的最小功能設計原則。根據這個原則,原有的介面要麼可以應對未來的擴充套件;不足的部分可以通過定義新的介面來實現;
模組之間的呼叫通過抽象介面進行,這樣即使實現層發生變化,也無需修改呼叫方的**。
介面可以被復用,但介面的實現卻不一定能被復用。
介面是穩定的,關閉的,但介面的實現是可變的,開放的。
可以通過對介面的不同實現以及類的繼承行為等為系統增加新的或改變系統原來的功能,實現軟體系統的柔性擴充套件。
實現方法:
1、面向介面程式設計,抽象構建框架,用實現擴充套件細節。
2、抽取父類共性,運用繼承和多型。
好處:提高系統的可復用性和可維護性。
個人理解:
1、對於整體架構 面向介面程式設計
2、對於類方法 修改關閉,對擴充套件開啟。通過繼承,aop,設計模式等等
黎克特制替換原則(liskov substitution principle,lsp),所有引用基類的地方必須能透明地使用其派生類的物件。
即是派生類應當可以替換基類並出現在基類能夠出現的任何地方,或者說如果我們把**中使用基類的地方用它的派生類所代替,**還能正常工作。
裡式替換原則的引申意義:子類可以擴充套件父類的功能,但不能改變父類原有的功能。
具體來說:
子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法。
子類中可以增加自己特有的方法。
當子類的方法過載父類的方法時,方法的前置條件(即方法的輸入/入參)要比父類方法的輸入引數更寬鬆。
當子類的方法實現父類的方法時(過載/重寫或實現抽象方法)的後置條件(即方法的輸出/返回值)要比父類更嚴格或相等。
優點:約束繼承氾濫,是開閉原則的一種體現。
加強程式的健壯性,同時變更時也可以做到非常好地提高程式的維護性、擴充套件性。降低需求變更時引入的風險。
重構違反lsp的設計
如果兩個具體的類a,b之間的關係違反了lsp 的設計,(假設是從b到a的繼承關係),那麼根據具體的情況可以在下面的兩種重構方案中選擇一種:
1、建立乙個新的抽象類c,作為兩個具體類的基類,將a,b的共同行為移動到c中來解決問題。
2、從b到a的繼承關係改為關聯關係。
個人理解:
1、對於繼承的約束,子類可擴充套件基類的方法,但不是修改基類原有方法
2、開閉原則的一種體現
迪公尺特原則(law of demeter lod)是指乙個物件應該對其他物件保持最少的了解,又叫最少知道原則(least knowledge principle,lkp),盡量降低類與類之間的耦合。
含義:1、乙個軟體實體應當盡可能少地與其他實體發生相互作用。
2、每乙個軟體實體對其他的實體都只有最少的了解,引數和返回值。
3、如實體之間必須發生聯絡必須是自身的』朋友』。
朋友的認定:
當前物件本身(this)
以參量形式傳入到當前物件方法中的物件
當前物件的例項變數直接引用的物件
當前物件的例項變數如果是乙個聚集,那麼聚集中的元素也都是朋友
當前物件所建立的物件
個人理解:
實體如必須與其他實體發成聯絡,先使其成為『朋友』。不能在方法內部通過new的方式直接與其他發生聯絡,同時儘量減少朋友的數量。
單一職責(****** responsibility pinciple,srp)是指不要存在多於乙個導致類變更的原因。假 設我們有乙個 class 負責兩個職責,一旦發生需求變更,修改其中乙個職責的邏輯**,有可能會導致 另乙個職責的功能發生故障。這樣一來,這個 class 存在兩個導致類變更的原因。如何解決這個問題呢? 我們就要給兩個職責分別用兩個 class 來實現,進行解耦。後期需求變更維護互不影響。這樣的設計, 可以降低類的複雜度,提高類的可讀性,提高系統的可維護性,降低變更引起的風險。總體來說就是一 個 class/inte***ce/method 只負責一項職責。
優點:單一職責原則從職責(改變理由)的側面上為我們對類(介面)的抽象的顆粒度建立了判斷基準:在為系統設計類(介面)的時候應該保證它們的單一職責性。
提高了實體的復用性,降低了類的複雜度、提高類的可讀性,提高系統的可維護性、降低變更引起的風險
個人理解:
1、以職責為基準細化實體class/inte***ce/method的粒度,不要寫萬能方法、萬能類,根據實際業務合理的拆分,以提高class/inte***ce/method的復用性為目的。
2、永遠不要讓乙個實體class/inte***ce/method存在多個改變的理由。
介面隔離原則(inte***ce segregation principle, isp)是指用多個專門的介面,而不使用單一的 總介面,客戶端不應該依賴它不需要的介面。
含義:1、介面的設計原則:介面的設計應該遵循最小介面原則,不要把使用者不使用的方法塞進同乙個介面裡。如果乙個介面的方法沒有被使用到,則說明該介面過胖,應該將其分割成幾個功能專一的介面。
2、介面的依賴(繼承)原則:如果乙個介面a繼承另乙個介面b,則介面a相當於繼承了介面b的方法,那麼繼承了介面b後的介面a也應該遵循上述原則:不應該包含使用者不使用的方法。 反之,則說明介面a被b給汙染了,應該重新設計它們的關係。
個人理解:
1、最小介面原則,如果乙個類實現了介面的無用方法,那麼介面的設計不合理。
2、細分介面,時間多個專用介面而不是乙個臃腫的介面
依賴倒置原則(dependence inversion principle,dip)是指設計**結構時,高層模組不應該依 賴底層模組,二者都應該依賴其抽象。抽象不應該依賴細節;細節應該依賴抽象。通過依賴倒置,可以 減少類與類之間的耦合性,提高系統的穩定性,提高**的可讀性和可維護性,並能夠降低修改程式所 造成的風險。
面向過程**:
物件導向依賴倒置**:
個人理解:
a. 高層模組不應該依賴於低層模組,二者都應該依賴於抽象
b. 抽象不應該依賴於細節,細節應該依賴於抽象
c.針對介面程式設計,不要針對實現程式設計。
合成復用原則(composite/aggregate reuse principle,carp)是指盡量使用物件組合(has-a)/ 聚合(contanis-a),而不是繼承關係達到軟體復用的目的。可以使系統更加靈活,降低類與類之間的耦 合度,乙個類的變化對其他類造成的影響相對較少。
在物件導向設計中,有兩種基本的辦法可以實現復用:
1、組合(實體依賴)復用實體
2、聚合(抽象介面)復用實體
3、繼承復用實體。
概念:組合:通過依賴已有實體的方式達到軟體復用的目的,即在乙個新的物件裡面使用一些已有的物件,使之成為新物件的一部分,新物件通過向這些物件的委派達到復用已有功能的目的。就是classa 依賴classb,達到復用classb方法的目的。
聚合:通過抽象功能、行為(has a)的方式,宣告介面,達到復用方法的目的。
使用繼承關係的場景:
1)派生類是基類的乙個特殊種類,而不是基類的乙個角色,也就是區分"has-a"和"is-a"。只有"is-a"關係才符合繼承關係,"has-a"關係應當用聚合來描述。
2)永遠不會出現需要將派生類換成另外乙個類的派生類的情況。如果不能肯定將來是否會變成另外乙個派生類的話,就不要使用繼承。
3)派生類具有擴充套件基類的責任,而不是具有置換掉(override)或登出掉(nullify)基類的責任。如果乙個派生類需要大量的置換掉基類的行為,那麼這個類就不應該是這個基類的派生類。
4)只有在分類學角度上有意義時,才可以使用繼承。
通過組合/聚合復用的優缺點
優點:1.新物件訪問子物件的唯一方法是通過子物件的介面。
2.這種復用是黑箱復用,因為子物件的內部細節是新物件所看不見的。
3.這種復用更好地支援封裝性。
4.這種復用實現上的相互依賴性比較小。
5.每乙個新的類可以將焦點集中在乙個任務上。
6.這種復用可以在執行時間內動態進行,新物件可以動態的引用與子物件型別相同的物件。
7.作為復用手段可以應用到幾乎任何環境中去。
缺點: 就是系統中會有較多的物件需要管理。
通過繼承來進行復用的優缺點
優點:新的實現較為容易,因為基類的大部分功能可以通過繼承的關係自動進入派生類。
修改和擴充套件繼承而來的實現較為容易。
缺點:繼承復用破壞封裝性,因為繼承將基類的實現細節暴露給派生類。由於基類的內部細節常常是對於派生類透明的,所以這種復用是透明的復用,又稱「白箱」復用。
如果基類發生改變,那麼派生類的實現也不得不發生改變。
從基類繼承而來的實現是靜態的,不可能在執行時間內發生改變,沒有足夠的靈活性。
個人理解:
1、注意軟體復用的方式 多組合聚合,少繼承.
即是**復用,多通過依賴,實現介面使用,少數場景下 通過繼承實現復用
2、繼承的使用場景
七大設計原則
開閉原則 定義 乙個軟體實體如類 模組和函式應該對擴充套件開放 對修改關閉 用抽象構建框架,用實現擴充套件細節 優點 提高軟體系統的可復用性及可維護性 依賴倒置原則 定義 高層模組不應該依賴低層模組,二者都應該依賴其抽象 抽象不應該依賴細節,細節應該依賴抽象 針對介面程式設計,不要針對實現程式設計 ...
七大設計原則
核心 解耦和增強內聚性 高內聚,低耦合 說明 就乙個類而言,應該只專注於做一件事和僅有乙個引起它變化的原因。所謂職責,我們可以理解他為功能,就是設計的這個類功能應該只有乙個,而不是兩個或更多。也可以理解為引用變化的原因,當你發現有兩個變化會要求我們修改這個類,那麼你就要考慮撤分這個類了。因為職責是變...
設計模式 七大設計原則
定義 應該有且只有乙個原因,引起類的變更 組合是一種強耦合關係,你我都有共同的生命週期,這種強耦合關係,不如直接使用介面實現 建議 介面一定要做到單一原則,類的設計盡量做到只有乙個原因引起變更 定義 所有使用父類的地方,必須能夠透明的使用其子類,反之不行 子類不能完整地實現父類的方法,或者父類的某些...