'設計模式分類以及六大設計原則'

設計模式 設計 軟件 虐殺原形 程序大牛 2019-08-06
"
"
設計模式分類以及六大設計原則

設計模式的分類

 根據其目的(模式是用來做什麼的)可分為創建型(Creational),結構型(Structural)和行為型(Behavioral)三種:
創建型模式主要用於創建對象。
結構型模式主要用於處理類或對象的組合。
行為型模式主要用於描述對類或對象怎樣交互和怎樣分配職責。
創建型模式
抽象工廠模式(Abstract Factory)
建造者模式(Builder)
工廠方法模式(Factory Method)
原型模式(Prototype)
單例模式(Singleton)
結構型模式
適配器模式(Adapter)
橋接模式(Bridge)
組合模式(Composite)
裝飾模式(Decorator)
外觀模式(Facade)
享元模式(Flyweight)
代理模式(Proxy)
行為型模式
職責鏈模式(Chain of Responsibility)
命令模式(Command)
解釋器模式(Interpreter)
迭代器模式(Iterator)
中介者模式(Mediator)
備忘錄模式(Memento)
觀察者模式(Observer)
狀態模式(State)
策略模式(Strategy)
模板方法模式(Template Method)
訪問者模式(Visitor)
根據範圍(模式主要是用於處理類之間關係還是處理對象之間的關係)可分為類模式和對象模式兩種:
類模式處理類和子類之間的關係,這些關係通過繼承建立,在編譯時刻就被確定下來,是屬於靜態的。
對象模式處理對象間的關係,這些關係在運行時刻變化,更具動態性。
類模式
工廠方法模式(Factory Method)
適配器模式(Adapter)
解釋器模式(Interpreter)
模板方法模式(Template Method)
對象模式
抽象工廠模式(Abstract Factory)
建造者模式(Builder)
原型模式(Prototype)
單例模式(Singleton)
橋接模式(Bridge)
組合模式(Composite)
裝飾模式(Decorator)
外觀模式(Facade)
享元模式(Flyweight)
代理模式(Proxy)
職責鏈模式(Chain of Responsibility)
命令模式(Command)
迭代器模式(Iterator)
中介者模式(Mediator)
備忘錄模式(Memento)
觀察者模式(Observer)
狀態模式(State)
策略模式(Strategy)
訪問者模式(Visitor)

六大原則

總原則:開閉原則

定義:一個軟件實體如類、模塊或函數應該對擴展開放,對修改關閉。

簡單的說就是,當一個軟件實體需要擴展的時候,不要去修改原有的代碼,而是去擴展原有的代碼。其實開閉原則是最基礎的一個原則,下面六個原則都是開閉原則的具體形態。

為什麼要採用開閉原則

1、對測試的影響:通過擴展實現變化,測試只需要對新增類進行單元測試即可,單元測試是孤立的,只需要保證新類提供的方法正確就行。而如果是修改類來實現變化,則該類相應的測試方法也都要隨著重構,而且當類很複雜時難免存在遺漏情況。

2、可以提高複用性:避免以後維護人員為了修改一個微小的缺陷或增加新功能,卻要在整個項目中到處查找相關的代碼逐一修改。

3、提高可維護性:開發新功能時,擴展一個類往往比修改一個類更容易。

4、面向對象開發的要求

單一職責原則

定義:應該有且僅有一個原因引起類的變更。

優點

1、類的複雜性降低。類的職責單一,複雜性自然就降低了。

2、可讀性高。

3、易維護。

4、變更引起的風險降低。

難點

1、"職責"和"變化原因"都是不可度量的,因項目、環境而異。

2、過細的劃分會引起類的劇增,人為的增加系統的複雜性。

建議

接口的設計一定要做到單一原則,類的設計儘量做到只有一個原因引起變化。

職責的劃分需要根據項目和經驗來權衡,既要保證職責的單一性,又要儘量避免過細的劃分。

里氏替換原則

定義:所有引用基類的地方都必須能透明地使用其子類的對象。

繼承的優點

1、代碼共享,提高代碼的重用性。

2、提高代碼的可擴展性。

3、提高產品或者項目的開放性。

繼承的缺點

1、繼承是侵入式的,只要繼承,就擁有了父類的屬性和方法。

2、降低代碼靈活性,子類擁有了父類的屬性和方法,多了一些約束。

3、增強了耦合性。父類的常量、變量或方法改動時,必須還要考慮子類的修改,可能會有大段代碼需要重構。

里氏替換原則四層含義

1、子類必須完全實現父類的方法

在類中調用其他類時務必使用父類或接口,如若不能,則說明類的設計已經違背LSP原則。

如果子類不能完整的實現父類的方法,或者父類的方法在子類中發生畸變,這建議斷開父子繼承關係,採用依賴、聚集、組合等方式代替繼承。

2、子類可以有自己的特性:即子類出現的地方父類未必可以出現。

3、覆蓋父類的方法時輸入參數可以被放大:輸入參數類型寬於父類的類型的覆蓋範圍,例如 hashmap -> map。

4、覆蓋父類的方法時輸出參數可以被縮小

依賴倒置原則

定義

1、高層模塊不應該依賴低層模塊,兩者都要改依賴其抽象(模塊間的依賴通過抽象產生,實現類不發生直接的依賴關係)

2、抽象不應該依賴細節(接口或者抽象類不依賴實現類)

3、細節可以依賴抽象(實現類依賴接口或者抽象類)

建議

1、每個類儘量都有接口或抽象類。

2、變量的表面類型儘量是接口或抽象類。

3、任何類都不應該從具體類派生(其實只要不是超過兩層的繼承都是可以忍受的)。

4、儘量不要複寫基類已實現的方法。

5、結合里氏替換原則使用。

面向接口編程

接口負責定義 public 屬性和方法,並且聲明與其它對象的依賴關係,抽象類負責公共構造部分的實現,實現類準確實現業務邏輯,同時在適當的時候對父類進行細化。

接口隔離原則

定義:客戶端不應該依賴他不需要的接口,類之間的依賴關係應該建立在最小的接口上。

四層含義

1、接口儘量要小,不要出現臃腫的接口。

2、接口要高內聚。

3、只提供訪問者需要的方法:每個接口中不存在子類用不到卻必須實現的方法,如果不然,就要將接口拆分。

4、接口設計是有限度的:接口設計粒度越小,系統越靈活。但是結構會越複雜、開發難度增加,可維護性降低。

建議

1、一個接口只服務一個子模塊或者業務邏輯。

2、儘量壓縮接口內的方法,保證方法都是有用的,避免臃腫。

3、已經被汙染的接口儘量去修改,若變更風險大,則採用適配器模式轉化處理。

4、深入瞭解業務邏輯,拒絕盲從。

迪克特法則(最少知道原則)

定義:一個對象應該對其他對象有最少的瞭解(低耦合)。

三層含義

1、一個類只與朋友交流,不和陌生類交流,方法儘量不引入類中不存在的對象。

2、儘量不要對外暴露過多的 public 方法和非靜態的 public 變量,儘量內斂。

3、自己的就是自己的。如果一個方法放在本類中,既不增加類間關係,也對本類不產生負面影響,那就放置在本類中。

總結

迪米特法則的核心觀念就是類間解耦,低耦合。其負面影響就是產生了大量的中轉或者跳轉類,導致系統複雜性提高,也為維護帶來了難度。需要反覆權衡,既做到結構清晰,又要高內聚低耦合。

如果一個類需要跳轉兩次以上才能訪問到另一個類,就需要想辦法重構了。

合成複用原則

定義

是在一個新的對象裡面使用一些已有的對象,使其成為新對象的一部分。新對象通過委派達到複用已有功能的效果。

優點

使用對象的合成/聚合將有助於你保持每個類被封裝,並被集中在單個任務上。這樣類和集成層次會保持較小規模,並且不太可能增長為不可控制的龐然大物。

缺點

通過這種方式複用建造的系統會有較多的對象需要管理;為了能將多個不同的對象作為組合塊來使用,必須仔細地對接口進行定義。

簡單地說:儘量首先使用合成/聚合的方式,而不是使用繼承。

"

相關推薦

推薦中...