大話設計模式之簡單工廠模式與策略模式
前言
- 設計模式(Design Pattern)是一套被反覆使用、多數人知曉的、經過分類的、代碼設計經驗的總結。
- 使用設計模式的目的:為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。 設計模式使代碼編寫真正工程化;設計模式是軟體工程的基石脈絡,如同大廈的結構一樣。
- 在介紹設計模式之前需要先介紹一下面向對象的特性和UML類圖。
面向對象的特點
- 封裝、繼承、多態。UML類圖
- 在UML類圖中,常見的有以下幾種關係: 泛化(Generalization), 實現(Realization),關聯(Association),聚合(Aggregation),組合(Composition),依賴(Dependency)
- 在UML類圖中矩形框表示一個類,類分三層,第一層是;類的名稱,如果是抽象類,則用斜體顯示,第二層表示特性,是欄位和屬性,第三層表示操作,通常是方法和行為。
- 注意前面符號,「+」表示public,「-」表示private,「#」表示protected。
- 【泛化關係】:是一種繼承關係,表示一般與特殊的關係,它指定了子類如何具體化父類的所有特徵和行為。例如:老虎是動物的一種,即有老虎的特性也有動物的共性。
【箭頭指向】:帶三角箭頭的實線,箭頭指向父類
- 【實現關係】:是一種類與介面的關係,表示類是介面所有特徵和行為的實現.
【箭頭指向】:帶三角箭頭的虛線,箭頭指向介面
- 【關聯關係】:是一種擁有的關係,它使一個類知道另一個類的屬性和方法;如:老師與學生,丈夫與妻子關聯可以是雙向的,也可以是單向的。雙向的關聯可以有兩個箭頭或者沒有箭頭,單向的關聯有一個箭頭。【代碼體現】:成員變數【箭頭及指向】:帶普通箭頭的實心線,指向被擁有者
- 【聚合關係】:是整體與部分的關係,且部分可以離開整體而單獨存在。如車和輪胎是整體和部分的關係,輪胎離開車仍然可以存在。聚合關係是關聯關係的一種,是強的關聯關係;關聯和聚合在語法上無法區分,必須考察具體的邏輯關係。【代碼體現】:成員變數【箭頭及指向】:帶空心菱形的實心線,菱形指向整體
- 【組合關係】:是整體與部分的關係,但部分不能離開整體而單獨存在。如公司和部門是整體和部分的關係,沒有公司就不存在部門。組合關係是關聯關係的一種,是比聚合關係還要強的關係,它要求普通的聚合關係中代表整體的對象負責代表部分的對象的生命周期。
【代碼體現】:成員變數
【箭頭及指向】:帶實心菱形的實線,菱形指向整體
+ 【依賴關係】:是一種使用的關係,即一個類的實現需要另一個類的協助,所以要盡量不使用雙向的互相依賴.
【代碼表現】:局部變數、方法的參數或者對靜態方法的調用
【箭頭及指向】:帶箭頭的虛線,指向被使用者
+ 各種關係的強弱順序:
泛化 = 實現 > 組合 > 聚合 > 關聯 > 依賴 + 下面這張UML圖,比較形象地展示了各種類圖關係:
簡單工廠模式
- 工廠模式介紹
- 工廠模式專門負責將大量有共同介面的類實例化,工廠模式可以動態決定將哪一個類實例化,不必事先知道要實例化那一個類。
- 工廠模式的幾種形態:
- 簡單工廠模式:又稱靜態工廠方法模式。
- 工廠方法模式:又稱多態性工廠模式。
- 抽象工廠模式:又稱 工具箱模式。
- 簡單工廠模式的舉例
//抽象產品角色 public interface Car{ public void drive(); } //具體產品角色 public class Benz implements Car{ public void drive() { System.out.println("Driving Benz "); } } public class Bmw implements Car{ public void drive() { System.out.println("Driving Bmw "); } } //工廠類角色 public class Driver{ //工廠方法.注意 返回類型為抽象產品角色 public static Car driverCar(String s)throws Exception{ //判斷邏輯,返回具體的產品角色給Client if(s.equalsIgnoreCase("Benz")) return new Benz(); else if(s.equalsIgnoreCase("Bmw")) return new Bmw(); else throw new Exception(); } }
策略模式
- 定義:它定義了演算法家族,分別封裝起來,讓他們之間可以可以互相替換,此模式讓演算法的變化,不會影響到使用演算法的客戶。
- Strategy類,定義了所有的支持的演算法的公共介面。
abstract class Strategy{ //演算法方法 public void AlgorithmInterface();}ConcreteStrategy類封裝了具體的演算法或行為,繼承Strategy類。public class ConcreteStrategyA extend Strategy{ //演算法A實現方法 public void AlgorithmInterface(){ //演算法A實現方法 }}public class ConcreteStrategyB extend Strategy{ //演算法B實現方法 public void AlgorithmInterface(){ //演算法B實現方法 }}Context類,用一個ConcreteStrategy來配置,維護一個對Strategy對象的引用。public class Context{ Strategy strategy; public Context(Strategy strategy){ //初始化時,傳入具體的策略對象 this.strategy = strategy; } //上下文介面 public void ContextInterface(){ //根據具體的策略對象調用其演算法方法 strategy.AlgorithmInterface(); }} //主函數代碼:public static void main(String[] args) { Context context; //由於實例化不同的策略,在調用context.AlgorithmInterface();時,所獲得的結果也不同。 context = new Context(new ConcreteStrategyA()); context.AlgorithmInterface(); context = new Context(new ConcreteStrategyB()); context.AlgorithmInterface();}
策略與工廠結合
- 修改Context類
public class Context{ Strategy strategy = null; //聲明一個介面對象 public Context(String type){ //初始化時,在Context類中實現簡單工廠的應用。 switch(type){ case "需求一": Strategy s1 = new ConcreteStrategyA(); strategy = s1; break; case "需求二": Strategy s2 = new ConcreteStrategyB(); strategy = s2; break; } } public double GetResult(){ return strategy..AlgorithmInterface(); }}
- 簡單工廠模式與策略與工廠結合的客戶端代碼對比
//工廠模式用法Strategy s = StrategyFactory.createStrategy(type);... = s.GetResult();//策略與工廠結合Context c = Context(type);... = c.GetResult();
- 總結:簡單工廠模式,客戶端需要兩個類,Strategy和StrategyFactory,而策略與工廠結合只需要一個類,Context類。降低了耦合性。
策略模式解析
- 策略模式是一種定義一系列演算法的方法,所有這些演算法完成的都是相同的工作,只是實現不同,它可以以相同的方式調用所有的演算法,減少了各種演算法類與使用演算法類之間的耦合。
- 優點:
- 簡化單元測試,因為每個演算法都有自己的類,可以通過自己的介面單獨測試,
- 將一系列行為封裝到一個個類中時,可以在這些行為的類中消除條件語句。
只要在分析過程中聽到需要在不同時間應用不同的業務規則,就可以考慮運用策略模式處理這種可能性變化。
100塊錢買來的假AI良心為你推薦以下文章:
譚慶波:100多本計算機類圖書無套路免費送譚慶波:送給程序員15本經典電子書關注微信公眾號【輪子工廠】後台回復關鍵字:
1.回復【圖書】:獲取15本新手自學編程,零基礎入門經典學習教材; 2.回復【我要造輪子】:獲取100多本我根據知乎上面關於計算機問題的高贊回答裡面的介紹整理出來的書籍; 3.回復【開發工具】:獲取幾大主流編程語言的開發工具~ 4.回復【ps教程】:獲取ps視頻免費教程; 5.回復【早起】:每天早上7點準時叫你起床; 希望能幫助到你~
推薦閱讀: