定義乙個軟體實體如類、模組和函式應該對擴充套件開放,對修改關閉。
問題由來
在軟體的生命週期內,因為變化、公升級和維護等原因需要對軟體原有**進行修改時,可能會給舊**中引入錯誤,也可能會使我們不得不對整個功能進行重構,並且需要原有**經過重新測試。
解決方案
當軟體需要變化時,盡量通過擴充套件軟體實體的行為來實現變化,而不是通過修改已有的**來實現變化。
表達用抽象構建框架,用實現擴充套件細節。因為抽象靈活性好,適應性廣,只要抽象的合理,可以基本保持軟體架構的穩定。而軟體中易變的細節,我們用從抽象派生的實現類來進行擴充套件,當軟體需要發生變化時,我們只需要根據需求重新派生乙個實現類來擴充套件就可以了。當然前提是我們的抽象要合理,要對需求的變更有前瞻性和預見性才行。
定義不要存在多於乙個導致類變更的原因。通俗的說,即乙個類只負責一項職責。
問題由來
類t負責兩個不同的職責:職責p1,職責p2。當由於職責p1需求發生改變而需要修改類t時,有可能會導致原本執行正常的職責p2功能發生故障。
解決方案
遵循單一職責原則。分別建立兩個類t1、t2,使t1完成職責p1功能,t2完成職責p2功能。這樣,當修改類t1時,不會使職責p2發生故障風險;同理,當修改t2時,也不會使職責p1發生故障風險。
表達不要讓責任擴散
定義所有引用基類的地方必須能透明地使用其子類的物件。
問題由來
有一功能p由類a完成,現在要擴充套件p,其中p由類a的子類b完成,則子類在完成的同時,可能會導致原來功能故障
解決方案
當使用繼承時,遵循黎克特制替換原則。類b繼承類a時,除新增新的方法完成新增功能外,盡量不要重寫父類a的方法,也盡量不要過載父類a的方法。
表達使用繼承的時候,不要隨便修改父類中已經實現的方法
定義高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。
問題由來
類a直接依賴類b,假如要將類a改為依賴類c,則必須通過修改類a的**來達成。這種場景下,類a一般是高層模組,負責複雜的業務邏輯;類b和類c是低層模組,負責基本的原子操作;假如修改類a,會給程式帶來不必要的風險。
解決方案
將類a修改為依賴介面i,類b和類c各自實現介面i,類a通過介面i間接與類b或者類c發生聯絡,則會大大降低修改類a的機率。
表達如果a依賴b,現在要改為依賴c,如果直接修改a有風險,可以讓a去依賴乙個介面,bc都實現這個介面,也就是策略模式
定義客戶端不應該依賴它不需要的介面;乙個類對另乙個類的依賴應該建立在最小的介面上。
問題由來
類a通過介面i依賴類b,類c通過介面i依賴類d,如果介面i對於類a和類b來說不是最小介面,則類b和類d必須去實現他們不需要的方法。
解決方案
將臃腫的介面i拆分為獨立的幾個介面,類a和類c分別與他們需要的介面建立依賴關係。也就是採用介面隔離原則
表達防止去實現不需要的介面方法,可以按介面拆分,避免臃腫。
定義乙個物件應該對其他物件保持最少的了解。
問題由來
類與類之間的關係越密切,耦合度越大,當乙個類發生改變時,對另乙個類的影響也越大。
解決方案
盡量降低類與類之間的耦合。
表達盡量降低類與類之間的耦合。
設計模式六大原則
0.05 設計模式 設計模式 規範 筆記 大話設計模式 物件導向的關鍵在於封裝,封裝好了才能很好的復用,達到單一職責和開放擴充套件 封閉更改的效果。1 單一職責原則 就乙個類而言,應該僅有乙個引起它變化的原因.增加功能不應該修改已有的 避免修改出錯及重複測試.如果你能夠想到多於乙個的動機去改變乙個類...
設計模式六大原則
0.05 設計模式 設計模式 規範 筆記 大話設計模式 物件導向的關鍵在於封裝,封裝好了才能很好的復用,達到單一職責和開放擴充套件 封閉更改的效果。1 單一職責原則 就乙個類而言,應該僅有乙個引起它變化的原因.增加功能不應該修改已有的 避免修改出錯及重複測試.如果你能夠想到多於乙個的動機去改變乙個類...
設計模式六大原則
參考文章 單一職責原則 single responsibility principle,srp 乙個類只負責乙個功能領域中的相應職責,或者可以定義為 就乙個類而言,應該只有乙個引起它變化的原因。開閉原則 open closed principle,ocp 乙個軟體實體應當對擴充套件開放,對修改關閉。...