前言:對于設(shè)計模式基礎(chǔ)概念可以去看[簡說設(shè)計模式之設(shè)計模式概述]
一、什么是策略模式
策略(Strategy)模式的定義:該模式定義了一系列算法,并將每個算法封裝起來,使它們可以相互替換,且算法的變化不會影響使用算法的客戶。策略模式屬于對象行為模式,它通過對算法進行封裝,把使用算法的責(zé)任和算法的實現(xiàn)分割開來,并委派給不同的對象對這些算法進行管理。
? 舉個例子:我們出門的時候會選擇不同的出行方式,比如騎自行車、坐公交、坐火車、坐飛機、坐火箭等等,這些出行方式,每一種都是一個策略。再比如我們?nèi)ス渖虉?,商場現(xiàn)在正在搞活動,有打折的、有滿減的、有返利的等等,其實不管商場如何進行促銷,說到底都是一些算法,這些算法本身只是一種策略,并且這些算法是隨時都可能互相替換的,比如針對同一件商品,今天打八折、明天滿100減30,這些策略間是可以互換的。
UML結(jié)構(gòu)圖如下:

其中,Context是上下文環(huán)境類,用一個具體ConcreteStrategy來配置,維護一個對Strategy對象的引用;Strategy是策略類,用于定義所有支持算法的公共接口;ConcreteStrategy是具體策略類,封裝了具體的算法或行為,實現(xiàn)于Strategy。
1. Context上下文
? Context上下文角色,也叫Context封裝角色,起承上啟下的作用,屏蔽高層模塊對策略、算法的直接訪問,封裝可能存在的變化。
class Context
{
private Strategy strategy;
public Strategy getStrategy()
{
return strategy;
}
public void setStrategy(Strategy strategy)
{
this.strategy=strategy;
}
public void strategyMethod()
{
strategy.strategyMethod();
}
}
2. 策略角色
抽象策略角色,是對策略、算法家族的抽象,通常為接口,定義每個策略或算法必須具有的方法和屬性。
interface Strategy
{
public void strategyMethod(); //策略方法
}
3. 具體策略角色
用于實現(xiàn)抽象策略中的操作,即實現(xiàn)具體的算法,下方用print代替。測試類共2個ConcreteStrategy,其它兩個類與ConcreteStrategyA同理,就不再贅述了。
class ConcreteStrategyA implements Strategy
{
public void strategyMethod()
{
System.out.println("具體策略A的策略方法被訪問!");
}
}
4.完整代碼
package strategy;
public class StrategyPattern
{
public static void main(String[] args)
{
Context c=new Context();
Strategy s=new ConcreteStrategyA();
c.setStrategy(s);
c.strategyMethod();
System.out.println("-----------------");
s=new ConcreteStrategyB();
c.setStrategy(s);
c.strategyMethod();
}
}
//抽象策略類
interface Strategy
{
public void strategyMethod(); //策略方法
}
//具體策略類A
class ConcreteStrategyA implements Strategy
{
public void strategyMethod()
{
System.out.println("具體策略A的策略方法被訪問!");
}
}
//具體策略類B
class ConcreteStrategyB implements Strategy
{
public void strategyMethod()
{
System.out.println("具體策略B的策略方法被訪問!");
}
}
//環(huán)境類
class Context
{
private Strategy strategy;
public Strategy getStrategy()
{
return strategy;
}
public void setStrategy(Strategy strategy)
{
this.strategy=strategy;
}
public void strategyMethod()
{
strategy.strategyMethod();
}
}
二、策略模式的實現(xiàn)
用策略模式實現(xiàn)旅游的出行方式。

三、策略模式的應(yīng)用
1. 何時使用
- 一個系統(tǒng)有許多類,而區(qū)分它們的只是他們直接的行為時
2. 方法
- 將這些算法封裝成一個一個的類,任意的替換
3. 優(yōu)點
- 算法可以自由切換
- 避免使用多重條件判斷(如果不用策略模式我們可能會使用多重條件語句,不利于維護)
- 擴展性良好,增加一個策略只需實現(xiàn)接口即可
4. 缺點
- 策略類數(shù)量會增多,每個策略都是一個類,復(fù)用的可能性很小
- 所有的策略類都需要對外暴露
5. 使用場景
- 多個類只有算法或行為上稍有不同的場景
- 算法需要自由切換的場景
- 需要屏蔽算法規(guī)則的場景
6. 應(yīng)用實例
- 出行方式,自行車、汽車等,每一種出行方式都是一個策略
- 商場促銷方式,打折、滿減等
7. 注意事項
- 如果一個系統(tǒng)的策略多于四個,就需要考慮使用混合模式來解決策略類膨脹的問題
四、策略模式的擴展
在一個使用策略模式的系統(tǒng)中,當存在的策略很多時,客戶端管理所有策略算法將變得很復(fù)雜,如果在環(huán)境類中使用策略工廠模式來管理這些策略類將大大減少客戶端的工作復(fù)雜度,其結(jié)構(gòu)圖 。
