策略模式
定義:
策略模式定義了演算法族,分別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變化獨立於使用演算法的客戶。(其實類似於if-else模式)
設計原則:
將一個類中經常改變或者將來可能改變的部分提取出來,作為一個介面然後在類中包含這個物件的例項,這樣類的例項在執行時就可以隨意呼叫實現了這個介面的類的行為。原理是用多型實現的。
適用場景:
系統有很多類,它們的區別僅在於行為不同,一個系統需要動態地在幾種演算法中選擇一種。
組成:
策略模式中包含三部分:
策略(Strategy):策略是一個介面,該介面定義若干個演算法標識,即定義了若干個抽象方法。
具體策略(ConcreteStrategy):具體策略是實現策略介面的類,具體策略實現策略介面所定義的抽象方法,即給出演算法標識的具體演算法。
上下文(Context):上下文是依賴於策略介面的類,即上下文包含有策略宣告的變數。上下文中提供一個方法,該方法委託策略變數呼叫具體策略所實現的策略介面中的方法。
優缺點:
優點:符合開閉原則,增加程式的可擴充套件性和可維護性;避免多個if-else判斷
缺點:客戶端必須知道所有策略類,並自行決定使用哪一個策略類
類圖:
Strategy介面定義了一個演算法族,均實現了behavior()方法。
Context是使用到該演算法族的類,它的dosomething()方法會呼叫behavior(),setStrategy(Strategy)方法可以動態地改變strategy物件,即動態改變Context使用的演算法。
tip:
一般情況下,策略模式會結合工廠模式或單例模式一起使用
使用策略模式的原始碼:
java.util.Comparator#compare()
javax.servlet.http.HttpServlet
javax.servlet.Filter#doFilter()
Spring框架中的Resourse以及初始化介面InstantiationStrategy
具體實現:
//定義一個策略介面
public interface tmpStrategy{
void quack();
}
//定義具體策略方法
//普通鴨子呱呱叫演算法
public class IsQuack implements tmpStrategy{
@Override
public void quack(){
System.out.println("普通鴨子呱呱叫");
}
}
//橡皮鴨子吱吱叫演算法
public class Squeak implements tmpStrategy{
@Override
public void quack(){
System.out.println("橡皮鴨子吱吱叫");
}
}
//木頭鴨子不會叫演算法
public class MuteQuack implements tmpStrategy{
@Override
public void quack(){
System.out.println("木頭鴨子不會叫");
}
}
//客戶端呼叫演算法
public class Context {
//注入策略介面以後,才可以選擇策略。
private tmpStrategy strategy;
public Context(tmpStrategy strategy){
this.strategy = strategy;
}
public void setQuackBehavior(){
strategy.quack();
}
public static void main(String[] args) {
System.out.println("guagua");
Context context1 = new Context(new IsQuack());
context1.setQuackBehavior();
System.out.println("zhizhi");
Context context2 = new Context(new Squeak());
context2.setQuackBehavior();
System.out.println("nono");
Context context3 = new Context(new MuteQuack());
context3.setQuackBehavior();
}
}