請直接看原文:
設計模式(十一)策略模式_某移動支付系統在實現賬戶資金轉入和轉出時需要進行身份驗證,該系統為用戶提供了-CSDN博客
--------------------------------------------------------------------------------------------------------------------------------?
前言
當我們寫代碼時總會遇到一種情況就是我們會有很多的選擇,由此衍生出很多的if…else,或者case。如果每個條件語句中包含了一個簡單的邏輯,那還比較容易處理,如果在一個條件語句中又包含了多個條件語句就會使得代碼變得臃腫,維護的成本也會加大,這顯然違背了開放封閉原則。這一講我們就來講策略模式,來看看它是怎么解決如上所說的問題的。
1.策略模式簡介
策略模式定義
定義一系列的算法,把每一個算法封裝起來, 并且使它們可相互替換。策略模式模式使得算法可獨立于使用它的客戶而獨立變化。
策略模式UML圖
- Context:用來操作策略的上下文環境。
- Stragety:策略的抽象。
- ConcreteStragetyA、ConcreteStragetyB:具體的策略實現。
2.策略模式簡單實現
這回我們還舉武俠的例子,張無忌作為一個大俠會遇到很多的對手,如果每遇到一個對手都用自己最厲害的武功去應戰這顯然是不明智的,于是張無忌想出了三種應戰的策略分別對付三個實力層次的對手。
定義策略接口
策略接口有一個fighting的方法用于戰斗:
public interface FightingStrategy {public void fighting();
}
具體策略實現
分別定義三個策略來實現策略接口,用來對付三個實力層次的對手:
public class WeakRivalStrategy implements FightingStrategy {@Overridepublic void fighting() {System.out.println("遇到了較弱的對手,張無忌使用太極劍");}
}
public class CommonRivalStrategy implements FightingStrategy {@Overridepublic void fighting() {System.out.println("遇到了普通的對手,張無忌使用圣火令神功");}
}
public class StrongRivalStrategy implements FightingStrategy {@Overridepublic void fighting() {System.out.println("遇到了強大的對手,張無忌使用乾坤大挪移");}
}
實現環境類
環境類的構造函數包含了策略類,通過傳進來不同的具體策略來調用不同策略的fighting方法:
public class Context {private FightingStrategy fightingStrategy;public Context(FightingStrategy fightingStrategy) {this.fightingStrategy = fightingStrategy;}public void fighting(){fightingStrategy.fighting();}
}
客戶端調用
張無忌遇到了三個對手:宋青書、滅絕師太和成昆,他分別采用了不同的策略來應戰:
public class ZhangWuJi {public static void main(String[] args) {Context context;//張無忌遇到對手宋青書,采用對弱的對手的策略context = new Context(new WeakRivalStrategy());context.fighting();//張無忌遇到對手滅絕師太,采用對普通的對手的策略context = new Context(new CommonRivalStrategy());context.fighting();//張無忌遇到對手成昆,采用對強勁的對手的策略context = new Context(new StrongRivalStrategy());context.fighting();}
}
3.策略模式優缺點和使用場景
優點
- 策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行為族。恰當使用繼承可以把公共的代碼轉移到父類里面,從而避免重復的代碼。
- 使用策略模式可以避免使用多重條件轉移語句。多重轉移語句不易維護,它把采取哪一種算法或采取哪一種行為的邏輯與算法或行為的邏輯混合在一起,統統列在一個多重轉移語句里面,比使用繼承的辦法還要原始和落后。
缺點
- 客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。這就意味著客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。換言之,策略模式只適用于客戶端知道所有的算法或行為的情況。
- 策略模式造成很多的策略類,每個具體策略類都會產生一個新類。有時候可以通過把依賴于環境的狀態保存到客戶端里面,而將策略類設計成可共享的,這樣策略類實例可以被不同客戶端使用。換言之,可以使用享元模式來減少對象的數量。
使用場景
- 對客戶隱藏具體策略(算法)的實現細節,彼此完全獨立。
- 針對同一類型問題的多種處理方式,僅僅是具體行為有差別時。
- 一個類定義了很多行為,而且這些行為在這個類里的操作以多個條件語句的形式出現。策略模式將相關的條件分支移入它們各自的 Strategy 類中以代替這些條件語句。