六大设计原则
寫在前邊:本文是自己的學習筆記。可能未必適合所有人學習,不喜勿噴。有錯誤希望大家能夠指出。
?
單一職責原則
原則分析:
1)一個類承擔的職責越多,它被復用的可能性越小,而且如果一個類承擔的職責過多,就相當于將這些職責耦合在一起,當其中一個職責變化時,可能會影響其他職責的運作。
2)類的職責主要包括兩個方面:數據職責和行為職責,數據職責通過其屬性來體現,而行為職責通過其方法來體現。
3)單一職責原則是實現高內聚、低耦合的指導方針。
單一職責原則的優點:
1)降低類的復雜性,一個類只負責一項職責,其邏輯肯定要比負責多項職責簡單的多;
2)提高類的可讀性
3)提高代碼的可維護性和復用性
4)降低因變更引起的風險,變更是必然的,如果單一職責原則遵守的好,當修改一個功能時,可以顯著降低對其他功能的影響。
怎樣做才算遵循單一指責原則:
? 不管對于一個類還是一個方法,盡可能的做到“少管閑事”,一個人做一件事就可以了。這樣做可以帶來的好處還有:我們在有修改的需求的時候,想要修改一個類也好,還是修改一個函數也好,都能不那么頭疼,都能少思考一點。
里氏替換原則
定義:
所有引用基類的地方必須能透明的使用其子類對象。
所有引用基類(父類)的地方必須能透明地使用其子類的對象。即子類能夠必須能夠替換基類能夠從出現的地方。子類也能在基類 的基礎上新增行為。
最后再用白話講一下:爸爸做的事都能交給兒子來完成,不管是誰做效果都是一樣的。
?
原則分析:
1)講的是基類和子類的關系,只有這種關系存在時,里氏代換原則才存在。
2)里氏代換原則可以通俗表述為:在軟件中如果能夠使用基類對象,那么一定能夠使用其子類對象。
3)里氏代換原則是實現開閉原則的重要方式之一。
?
?繼承的優點
?代碼共享,減少類數量,每個子類都擁有父類的方法和屬性
?提高代碼的可重用性
?提高代碼的可擴展性
?提高產品或項目的開放性
?
?繼承的缺點
?繼承是入侵式的。只要繼承,就必須擁有父類的所有屬性和方法
?降低代碼的靈活性。子類必須擁有父類的屬性和方法,受到限制
?增強了耦合性。當父類修改時,必須考慮子類的修改,這種修改可能造成大片的代碼需要重構
?
? 里氏替換原則為良好的繼承定義了規范,包含4層含義:
p?? 子類必須完全實現父類的方法;
p?? 子類可以有自己的個性;
p?? 覆蓋或實現父類的方法時輸入參數可以被放大;
p?? 覆蓋或實現父類的方法時輸出結果可以被縮小。
?
依賴倒置原則
? ?先談我的理解:本來我們覺得類之間的關系,都因該是直接調用。然而這樣做并不好,因為我們想要修改是比較吃力的。所以前人想到通過使用接口的形式,來降低耦合度。使用依賴倒置原則避免了牽一發而動全身的麻煩。
? 依賴倒置原則的核心就是要我們面向接口編程,理解了面向接口編程,也就理解了依賴倒置。
?
?包括三層含義 :
p高層模塊不應該依賴底層模塊,兩者都依賴其抽象
p抽象不依賴細節
p細節應該依賴于抽象
?
原則分析:
1)如果說開閉原則是面向對象設計的目標,依賴倒置原則是到達面向設計“開閉”原則的手段。如果要達到最好的“開閉”原則,就要盡量的遵守依賴倒置原則。
2)依賴倒置原則的常用實現方式之一是在代碼中使用抽象類,而將具體類放在配置文件中。
3)類之間的耦合:零耦合關系,具體耦合關系,抽象耦合關系。依賴倒置原則要求客戶端依賴于抽象耦合,以抽象方式耦合是依賴倒置原則的關鍵。
?
在Java語言中,抽象就是指接口或抽象類,兩者都是不能直接被實例化的;細節就是具體的實現類,實現類實現了接口或繼承了抽象類,其特點是可以直接被實例化
?
依賴倒置原則在Java中的體現:
?模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關系,其依賴關系是通過接口或抽象類產生
?接口或抽象類不依賴于實現類
?實現類依賴于接口或抽象類
依賴倒置原則可以減少類間的耦合性,提高系統的穩定性,降低并行開發引起的風險,提高代碼的可讀性和可維護性
?
接口隔離原則
? 還是先談我的感受:接口隔離原則和單一職責原則有點相近的意味,干的事目的相近。比方說,一個接口中有比較多的方法,那么就有可能有許多的類都想要實現這個接口。高耦合是我們不想看到的,所以我們就要把它撕碎,做法就是將接口盡可能的拆分,拆分盡可能的合理。
?接口
p實例接口:是對一個類型的實物所具有的方法特征的描述。包含了一系列不被實現的方法,而把這些方法的實現交給繼承它的類。
p類接口:是指在Java中使用interface嚴格定義的接口。
?
?接口隔離原則有如下兩種定義:
p客戶端不應該依賴它不需要的接口;
p類間的依賴關系應該建立在最小的接口上
?
?接口隔離原則的具體的含義如下 :
p一個類對另外一個類的依賴性應當是建立在最小的接口上的
p一個接口代表一個角色,不應當將不同的角色都交給一個接口。沒有關系的接口合并在一起,形成一個臃腫的大接口,這是對角色和接口的污染。因此使用多個專門的接口比使用單一的總接口要好
p不應該強迫客戶依賴于它們不用的方法。接口屬于客戶,不屬于它所在的類層次結構。即不要強迫客戶使用它們不用的方法,否則這些客戶就會面臨由于這些不使用的方法的改變所帶來的改變 ?
?
接口隔離原則與單一職責原則的對比
其一,單一職責原則注重的是職責;而接口隔離原則注重對接口依賴的隔離。
其二,單一職責原則主要是約束類,其次才是接口和方法,它針對的是程序中的實現和細節;而接口隔離原則主要約束接口,主要針對抽象,針對程序整體框架的構建.。
?
迪米特法則
? 仍然是先談我的感受:這個法則想要做的是:一個對象應當對其他對象盡可能少的了解。知道的越少,牽連就越少,修改起來就越容易。這樣做達到高內聚的目的。
??迪米特法則的核心觀念就是類之間的解耦、弱耦合,只有弱耦合了以后,類的復用率才可以提高
?
?迪米特法則具有代表性的表述 :
p只與你直接的朋友們通信
p不要跟“陌生人”說話
p每一個軟件單位對其他的單位都只有最少的了解,這些了解僅局限于那些與本單位密切相關的軟件單位
?
問題由來:
類與類之間的關系越密切,耦合度越大,當一個類發生改變時,對另一個類的影響也越大。
解決方案:
盡量降低類與類之間的耦合。
法則分析:
1)朋友類:
在迪米特法則中,對于一個對象,其朋友包括以下幾類:
(1) 當前對象本身(this);
(2) 以參數形式傳入到當前對象方法中的對象;
(3) 當前對象的成員對象;
(4) 如果當前對象的成員對象是一個集合,那么集合中的元素也都是朋友;
(5) 當前對象所創建的對象。
任何一個對象,如果滿足上面的條件之一,就是當前對象的“朋友”,否則就是“陌生人”。
?
迪米特法則的主要用途:在于控制信息的過載。
?在類的劃分上,應當盡量創建松耦合的類,類之間的耦合度越低,就越有利于復用,一個處在松耦合中的類一旦被修改,不會對關聯的類造成太大波及;
?在類的結構設計上,每一個類都應當盡量降低其成員變量和成員函數的訪問權限;
?在類的設計上,只要有可能,一個類型應當設計成不變類;
?在對其他類的引用上,一個對象對其他對象的引用應當降到最低。
?
開閉原則
? 先談自己的理解:一個軟件實體應當對擴展開放,對修改關閉。
? 為什么這樣做呢:對軟件的修改是關閉的,因為想要修改原來的代碼。在不清楚代碼邏輯的情況下,很容易出現很多的問題。為了安全考慮,對代碼的修改是關閉的。但是系統不可能是一成不變的,功能肯定是要增加的,所以說擴展開放的。
開閉原則的作用
p提高復用性
p提高可維護性
p提高靈活性
p易于測試
原則分析 :
1)當軟件實體因需求要變化時, 盡量通過擴展已有軟件實體,可以提供新的行為,以滿足對軟件的新的需求,而不是修改已有的代碼,使變化中的軟件有一定的適應性和靈活性。
2)實現開閉原則的關鍵就是抽象化。
3)可變性的封閉原則:找到系統的可變因素,將它封裝起來. 這是對“開-閉”原則最好的實現。
開閉原則的應用:
?
需求變更:
? 按照9折銷售圖書 ?遵照“開閉原則”中對修改關閉的原則,不能直接修改IBook接口和NovelBook類,而是通過增加一個子類OffNovelBook來完成
原則總結:
開閉原則是面向對象設計中最基礎的設計原則,它指導我們如何建立穩定靈活的系統。1
只要我們對前面5項原則遵守的好了,設計出的軟件自然是符合開閉原則的
開閉原則無非就是想表達:用抽象構建框架,用實現擴展細節。
再回想一下前面說的5項原則,恰恰是告訴我們用抽象構建框架,用實現擴展細節的注意事項而已:
- ? ? ? ? ? ? 單一職責原則告訴我們實現類要職責單一;
- ? ? ? ? ? ? 里氏替換原則告訴我們不要破壞繼承體系;
- ? ? ? ? ? ? 依賴倒置原則告訴我們要面向接口編程;
- ? ? ? ? ? ? 接口隔離原則告訴我們在設計接口的時候要精簡單一;
- ? ? ? ? ? ? ?迪米特法則告訴我們要降低耦合。
?? ?而開閉原則是總綱,他告訴我們要對擴展開放,對修改關閉。
總結
- 上一篇: 部署windows服务
- 下一篇: switchHosts 介绍