設計模式---面向對象設計原則

一:爲何提倡面向對象設計?

變化時複用的天敵!
面向對象設計的最大優點在於:抵禦變化

二:從新認識面向對象

(一)理解隔離變化:

從宏觀層面來看,面向對象的構建方式更能適應軟件的變化,能將變化所帶來的影響減爲最小(隔離不是絕對的)

(二)各司其職

從微觀層面來看,面向對象的方式更強調各個類的」責任「。
因爲需求變化致使的新增類型不該該影響原來類型的實現。---是所謂的各負其責

(三)對象是什麼:

從語言層面來看,對象封裝了代碼和數據。
從規格層面講,對象是一系列可被使用的公共接口。
從概念層面講,對象是某種擁有責任的抽象。

三:設計模式基本原則

最終目的:高內聚,低耦合

(一)依賴倒置原則(DIP)

高層模塊(穩定)不該該依賴於低層模塊(變化),兩者都應該依賴於抽象(穩定)。 抽象(穩定)不該該依賴於實現細節(變化),實現細節應該依賴於抽象(穩定)。

傳統過程設計:傾向因而高層次的模塊依賴於低層次的模塊,抽象層依賴於具體層(高度依賴)

依賴倒置實現解耦合,將上面的依賴關係倒轉過來

(二)開放封閉原則(OCP)

對擴展開放,對更改封閉 類模塊應該是可拓展的,可是不可修改
類的改動是經過增長代碼進行的,而不是修改源代碼
父類指針指向子類對象,使用多態等來擴展功能,某一個錯誤不會引發全局錯誤
軟件實體應該是可擴展,而不可修改的。也就是說,對擴展是開放的,而對修改是封閉的。

原來的結構設計:將全部功能放在某一個大類中,致使業務擴展性差,修改都是在一個類模塊中(易出現關聯錯誤)

符合開發封閉原則的設計:

擴展方便

(三)單一職責原則(SRP)

類的職責要單一,對外只提供一種功能,而引發類變化的緣由只有一個
功能分開,各爲一類。缺點:致使類太多
一個類應該僅有一個引發它變化的緣由。
變化的方向隱含着類的責任
若是一個類承擔的職責過多,就等於把這些職責耦合在一塊兒了。
一個職責的變化可能會削弱或者抑制這個類完成其餘職責的能力。
這種耦合會致使脆弱的設計,當發生變化時,設計會遭受到意想不到的破壞。
而若是想要避免這種現象的發生,就要儘量的遵照單一職責原則。
此原則的核心就是解耦和加強內聚性

問題由來

T負責兩個不一樣的職責:職責P1,職責P2。當因爲職責P1需求發生改變而須要修改類T時,有可能會致使本來運行正常的職責P2功能發生故障。也就是說職責P1和P2被耦合在了一塊兒。

解決方法

職責擴散:由於某種緣由,某一職責被分化爲顆粒度更細的多個職責了

遵照單一職責原則,將不一樣的職責封裝到不一樣的類或模塊中。

優勢

1)下降類的複雜度;
(2)提升類的可讀性,提升系統的可維護性;
(3)下降變動引發的風險(下降對其餘功能的影響)

(四)里氏替換原則(LSP)(多態)

設計原則之里氏替換原則

任何抽象類出現的地方,均可以用他的實現類進行替換(多態)。實際就是虛擬機制,語言級別實現面向對象功能
子類必須可以替換它們的基類(IS-A)。
繼承表達類型抽象。

原則:子類能夠擴展父類的功能,但不能改變父類原有的功能。

父類能出現的地方均可以用子類來代替,並且換成子類也不會出現任何錯誤或異常,而使用者也無需知道是父類仍是子類,
但反過來則不成立
     1. 子類必須徹底實現父類的抽象方法,但不能覆蓋父類的非抽象方法;
     2. 子類中能夠增長本身特有的方法;
     3. 當子類的方法重載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數要更寬鬆;
     4.當子類的方法實現父類的抽象方法時,方法的後置條件(即方法的返回值)要比父類更嚴格。

優勢:

     1. 提升代碼的重用性,子類擁有父類的方法和屬性;
     2. 提升代碼的可擴展性,子類可形似於父類,但異於父類,保留自個人特性;

缺點:

     1. 繼承是侵入性的,只要繼承就必須擁有父類的全部方法和屬性,在必定程度上約束了子類,下降了代碼的靈活性;
     2. 增長了耦合,當父類的常量、變量或者方法被修改了,須要考慮子類的修改,因此一旦父類有了變更,極可能會形成
        很是糟糕的結果,要重構大量的代碼。

(五)接口隔離原則(ISP)

接口隔離原則

不該該強迫客戶程序依賴它們不用的方法。 接口應該小而完備。
一個接口應該只提供一種對外功能,不該該把全部操做都封裝到一個接口中去

接口隔離原則和單一職責原則的區別

接口隔離原則與單一職責原則的審視角度不相同。單一職責原則要求是類和接口的職責單一,注重的是職責,這是業務邏輯上的劃分。
接口隔離原則要求接口的方法儘可能少。

接口要儘可能小

這是接口隔離原則的核心定義,接口要儘可能小,不要出現臃腫的接口,可是小也是有限度的,不能違背單一職責原則。

接口要高內聚

高內聚就是提升接口,類,模塊的處理能力,減小對外的交互。具體到接口隔離原則就是要求在接口中儘可能減小公佈public方法,接口是對外的承諾,承諾越少對系統開發越有利,變動的風險就越少。

原則

一個接口只服務於一個子模塊或業務邏輯
經過業務邏輯壓縮接口中的public方法,接口要不斷的精簡,以達到接口不斷完善
已經被污染的接口,儘可能去修改,若變動的風險較大,則採用適配器進行轉化處理

(六)優先使用對象組合,而不是類繼承

理解組合對象與類繼承

類繼承一般爲「白箱複用」,對象組合一般爲"黑箱複用"繼承在某種程度上破壞了封裝性,子類父類耦合度高。
而對象組合則只要求被組合的對象具備良好定義的接口,耦合度低。
若是使用了繼承,會致使父類的任何變換均可能影響到子類的行爲。
若是使用對象組合,就下降了這種依賴關係
對象組合要求被組合的對象具備良好定義的接口。

(七)封裝變化點

使用封裝來建立對象之間的分界層,讓設計者能夠在分界層的一側進行修改,而不會對另外一側產生不良的影響,從而實現層次間的鬆耦合。
例如:facade模式(外觀模式)

(八)迪米特法則:針對接口編程,而不是針對實現編程

不將變量類型聲明爲某個特定的具體類,而是聲明爲某個接口。
客戶程序無需獲知對象的具體類型,只須要知道對象所具備的接口。
減小系統中各部分的依賴關係,從而實現」高內聚、鬆耦合「的類型設計方案。
一個對象應該對其餘對象儘量少的瞭解,從而下降各個對象之間的耦合,提升系統的可維護性。
例如在一個程序中,各個模塊之間相互調用時,一般會提供一個統一的接口來實現,這樣其餘模塊不須要了解另外一個模塊的內部實現細節,
這樣當一個模塊內部的實現發生改變時,不會影響其餘模塊的使用(黑盒原理)

四:面向接口設計

產業強盛的標誌就是接口便準化。

五:將設計原則提高爲設計經驗

設計習語 Design Idioms
Design Idioms描述與特定編程語言相關的低層模式,技巧,慣用法。
設計模式 Design Patterns
Design Patterns主要描述的是」類與相互通訊的對象之間的組織關係」,包括它們的角色、職責、協做方式等方面。
架構模式 Architectural Patterns
Architectural Patterns描述系統中與基本結構組織關係密切的高層模式,包括子系統劃分,職責,以及如何組織它們之間關係的規則。
相關文章
相關標籤/搜索