一.架構(gòu)師內(nèi)功心法之設(shè)計原則
1.為什么要學(xué)習(xí)軟件架構(gòu)設(shè)計原則
1.1.課程目標(biāo)
- 通過對節(jié)課內(nèi)容的學(xué)習(xí),了解設(shè)計原則的重要性。
- 掌握七大設(shè)計原則的具體內(nèi)容。
1.2.內(nèi)容定位
學(xué)習(xí)設(shè)計原則,學(xué)習(xí)設(shè)計模式的基礎(chǔ)。在實際開發(fā)過程中,并不是一定要求所有代碼都遵循設(shè)計原則,我們要考慮人力、時間、成本、質(zhì)量,不是刻意追求完美,要在適當(dāng)?shù)膱鼍?/strong>遵循設(shè)計原則,體現(xiàn)的是一種平衡取舍,幫助我們設(shè)計出更加優(yōu)雅的代碼結(jié)構(gòu)。
1.3.七大設(shè)計原則
- 第1章 Open-Closed Principle 開閉原則
- 第2章 Dependence Inversion Principle 依賴倒置原則
- 第3章 Simple Responsibility Principle 單一職責(zé)原則
- 第4章 Interface Segregation Principle 接口隔離原則
- 第5章 Law of Demeter 迪米特法則
- 第6章 Liskov Substitution Principle 里氏替換原則
- 第7章 Composite&Aggregate Reuse Principle 合成復(fù)用原則
1.3.1.開閉原則
-
定義
- 開閉原則(Open-Closed Principle, OCP)是指一個軟件實體如類、模塊和函數(shù)應(yīng)該對擴展開放,
對修改關(guān)閉。所謂的開閉,也正是對擴展和修改兩個行為的一個原則。強調(diào)的是用抽象構(gòu)建框架,用實現(xiàn)擴展細(xì)節(jié)。 - 開閉原則,是面向?qū)ο笤O(shè)計中最基礎(chǔ)的設(shè)計原則。它指導(dǎo)我們?nèi)绾谓⒎€(wěn)定靈活的系統(tǒng),例如:我們版本更新,我盡可能不修改源代碼,但是可以增加新功能。
- 實現(xiàn)開閉原則的核心思想就是面向抽象編程。
- 開閉原則(Open-Closed Principle, OCP)是指一個軟件實體如類、模塊和函數(shù)應(yīng)該對擴展開放,
-
總結(jié)
- 對修改關(guān)閉,對擴展開放
- 簡單說:就是不修改原有實現(xiàn)類,而是新寫實現(xiàn)類。
- 缺點:會導(dǎo)致代碼臃腫。
1.3.2.依賴倒置原則
-
定義
- 依賴倒置原則(Dependence Inversion Principle,DIP)是指設(shè)計代碼結(jié)構(gòu)時,高層模塊不應(yīng)該依
賴底層模塊,二者都應(yīng)該依賴其抽象。抽象不應(yīng)該依賴細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴抽象。通過依賴倒置,可以
減少類與類之間的耦合性,提高系統(tǒng)的穩(wěn)定性,提高代碼的可讀性和可維護性,并能夠降低修改程序所造成的風(fēng)險。 - 以抽象為基準(zhǔn)比以細(xì)節(jié)為基準(zhǔn)搭建起來的架構(gòu)要穩(wěn)定得多,因此大家在拿到需求之后,要面向接口編程,先頂層再細(xì)節(jié)來設(shè)計代碼結(jié)構(gòu)。
- 依賴倒置原則(Dependence Inversion Principle,DIP)是指設(shè)計代碼結(jié)構(gòu)時,高層模塊不應(yīng)該依
-
總結(jié)
- 倒置:先框架,后細(xì)節(jié)。
1.3.3.單一職責(zé)原則
-
定義
- 單一職責(zé)(Simple Responsibility Principle,SRP)是指不要存在多于一個導(dǎo)致類變更的原因。假
設(shè)我們有一個Class負(fù)責(zé)兩個職責(zé),一旦發(fā)生需求變更,修改其中一個職責(zé)的邏輯代碼,有可能會導(dǎo)致
另一個職責(zé)的功能發(fā)生故障。這樣一來,這個Class存在兩個導(dǎo)致類變更的原因。如何解決這個問題呢?
我們就要給兩個職責(zé)分別用兩個 Class來實現(xiàn),進行解耦。后期需求變更維護互不影響。這樣的設(shè)計,
可以降低類的復(fù)雜度,提高類的可讀性,提高系統(tǒng)的可維護性,降低變更引起的風(fēng)險??傮w來說就是一
個Class/Interface/Method只負(fù)責(zé)一項職責(zé)。
- 單一職責(zé)(Simple Responsibility Principle,SRP)是指不要存在多于一個導(dǎo)致類變更的原因。假
-
總結(jié)
- 職責(zé)單一
- 一個類只做一件事
1.3.4.接口隔離原則
-
定義
- 接口隔離原則(Interface Segregation Principle, ISP)是指用多個專門的接口,而不使用單一的總接口,客戶端不應(yīng)該依賴它不需要的接口。這個原則指導(dǎo)我們在設(shè)計接口時應(yīng)當(dāng)注意一下幾點:
一個類對一類的依賴應(yīng)該建立在最小的接口之上。
建立單一接口,不要建立龐大臃腫的接口。
盡量細(xì)化接口,接口中的方法盡量少(不是越少越好,一定要適度)。
- 接口隔離原則符合我們常說的高內(nèi)聚低耦合的設(shè)計思想,從而使得類具有很好的可讀性、可擴展性
和可維護性。我們在設(shè)計接口的時候,要多花時間去思考,要考慮業(yè)務(wù)模型,包括以后有可能發(fā)生變更
的地方還要做一些預(yù)判。所以,對于抽象,對業(yè)務(wù)模型的理解是非常重要的。
- 接口隔離原則(Interface Segregation Principle, ISP)是指用多個專門的接口,而不使用單一的總接口,客戶端不應(yīng)該依賴它不需要的接口。這個原則指導(dǎo)我們在設(shè)計接口時應(yīng)當(dāng)注意一下幾點:
-
總結(jié)
- 接口隔離原則和單一職責(zé)原則區(qū)別?
- 接口隔離:指的接口
- 單一職責(zé):指的是類和方法
1.3.5.迪米特法則
-
定義
- 迪米特原則(Law of Demeter LoD)是指一個對象應(yīng)該對其他對象保持最少的了解,又叫最少知道原則(Least Knowledge Principle,LKP),盡量降低類與類之間的耦合。迪米特原則主要強調(diào)只和朋友交流,不和陌生人說話。出現(xiàn)在成員變量、方法的輸入、輸出參數(shù)中的類都可以稱之為成員朋友類,
而出現(xiàn)在方法體內(nèi)部的類不屬于朋友類。
- 迪米特原則(Law of Demeter LoD)是指一個對象應(yīng)該對其他對象保持最少的了解,又叫最少知道原則(Least Knowledge Principle,LKP),盡量降低類與類之間的耦合。迪米特原則主要強調(diào)只和朋友交流,不和陌生人說話。出現(xiàn)在成員變量、方法的輸入、輸出參數(shù)中的類都可以稱之為成員朋友類,
-
總結(jié)
- 參照訪問修飾符
-
聚合vs組合
- 聚合:個體與群體
- 組合:頭和身體,相同生命周期
1.3.6.里氏替換原則
-
定義
- 里氏替換原則(Liskov Substitution Principle,LSP)是指如果對每一個類型為 T1 的對象 o1,都有
類型為T2 的對象 o2,使得以T1 定義的所有程序 P 在所有的對象o1都替換成 o2時,程序 P 的行為沒
有發(fā)生變化,那么類型T2是類型T1的子類型。 - 可以理解為一個軟件實體如果適用一個父類的話,
那一定是適用于其子類,所有引用父類的地方必須能透明地使用其子類的對象,子類對象能夠替換父類
對象,而程序邏輯不變。 - 引申含義:子類可以擴展父類的功能,但不能改變父類原有的功能。
- 子類可以實現(xiàn)父類的抽象方法,但不能覆蓋父類的非抽象方法。
- 子類中可以增加自己特有的方法。
- 當(dāng)子類的方法重載父類的方法時,方法的前置條件(即方法的輸入/入?yún)ⅲ┮雀割惙椒ǖ妮斎雲(yún)?shù)更寬松。
- 當(dāng)子類的方法實現(xiàn)父類的方法時(重寫/重載或?qū)崿F(xiàn)抽象方法),方法的后置條件(即方法的輸
出/返回值)要比父類更嚴(yán)格或相等。
- 里氏替換原則(Liskov Substitution Principle,LSP)是指如果對每一個類型為 T1 的對象 o1,都有
-
總結(jié)
- 子類不能改變父類原有方法,可以新增方法。
1.3.7.合成復(fù)用原則
-
定義
- 合成復(fù)用原則(Composite/Aggregate Reuse Principle,CARP)是指盡量使用對象組合(has-a)/
聚合(contains-a),而不是繼承關(guān)系達到軟件復(fù)用的目的??梢允瓜到y(tǒng)更加靈活,降低類與類之間的耦
合度,一個類的變化對其他類造成的影響相對較少。 -
繼承我們叫做白箱復(fù)用,相當(dāng)于把所有的實現(xiàn)細(xì)節(jié)暴露給子類。組合/聚合也稱之為黑箱復(fù)用,對類以外的對象是無法獲取到實現(xiàn)細(xì)節(jié)的。要根據(jù)具體的業(yè)務(wù)場景來做代碼設(shè)計,其實也都需要遵循 OOP
模型。
- 合成復(fù)用原則(Composite/Aggregate Reuse Principle,CARP)是指盡量使用對象組合(has-a)/
-
總結(jié)
- 多用聚合組合代替繼承原則
1.4.設(shè)計原則總結(jié)
學(xué)習(xí)設(shè)計原則,學(xué)習(xí)設(shè)計模式的基礎(chǔ)。在實際開發(fā)過程中,并不是一定要求所有代碼都遵循設(shè)計原
則,我們要考慮人力、時間、成本、質(zhì)量,不是刻意追求完美,要在適合的場景遵循設(shè)計原則,體現(xiàn)的是一種平衡取舍,幫助我們設(shè)計出更加優(yōu)雅的代碼結(jié)構(gòu)。