更新時間:2018年12月07日11時48分 來源:傳智播客 瀏覽次數(shù):
---
typora-root-url: pic
---
# 設(shè)計模式之策略模式
## 概述
? 策略模式是指有一定行動內(nèi)容的相對穩(wěn)定的策略名稱。策略模式在古代中又稱“計策”,簡稱“計”,如《漢書·高帝紀(jì)上》:“漢王從其計”。這里的“計”指的就是計謀、策略。策略模式就針對不同的情況使用不同的方法。簡單點講,像我們寫代碼時總會出很多的if…else,或者case,如果在一個條件語句中又包含了多個條件語句就會使得代碼變得臃腫,維護(hù)的成本也會加大,而策略模式就能較好的解決這個問題。
## 重要的角色
1. 抽象策略(Strategy)角色,這是一個抽象角色,通常由一個接口或抽象類實現(xiàn)。定義了所有的具體策略類所需要實現(xiàn)的方法
2. 具體策略(ConcreteStrategy)角色:實現(xiàn)了相關(guān)的算法或行為。
3. 環(huán)境(Context)角色:持有一個Strategy的引用。
## 應(yīng)用場景
* 針對同一類型問題的多種處理方式,僅僅是具體行為或算法差別時。
* 需要安全地封裝多種同一類型的操作,同時又達(dá)到解藕的效果
* 出現(xiàn)同一抽象類有多個子類,而又需要使用 if-else 或者 switch-case 來選擇具體子類時。
## 策略模式結(jié)構(gòu)圖
![1](1.png)
### 說明
* Strategy是一個接口,定義了了具體實現(xiàn)類需要實現(xiàn)的方法
* ConcreteStrategyA、ConcreteStrategyB、ConcreteStrategyC 都實現(xiàn)了Strategy接口
* Context 是一個環(huán)境類,用于調(diào)動不同策略
## 舉例
? 商家的活動:針對不同節(jié)假日,商家總會對他們的商品做各種優(yōu)惠活動,比如,有打折,有贈送,還滿減,優(yōu)惠券等,也有一些商品不參與活動,那么計算價格時就應(yīng)該保留原價。
## 分析
? 這里我們可以把打折、贈送、滿減、優(yōu)惠券等的這些活動看成是一個個具體的策略類,商家的活動就是環(huán)境Context,商家舉行活動就會調(diào)用不同的策略。從此之后,無論商家增加多少活動、改變活動,我們只需增加實現(xiàn)類便可。
## 代碼實現(xiàn)
### 1. 創(chuàng)建普通java工程
? ![2](2.png)
### 2. IStrategy
```java
/**
* 策略接口
*/
public interface IStrategy {
/**
* 不同策略共有的方法
*/
void strategy();
}
```
### 3. Gif 贈送策略
```java
/**
* 贈送策略
*/
public class Gif implements IStrategy {
@Override
public void strategy() {
System.out.println("買三送一");
}
}
```
### 4. FullReduction 滿減策略
```java
/**
* 滿減策略
* 滿100減30元
*/
public class FullReduction implements IStrategy {
public void strategy() {
System.out.println("滿100減30元");
}
}
```
### 5. Discount 折扣策略
```java
/**
* 打折策略
*/
public class Discount implements IStrategy {
@Override
public void strategy() {
System.out.println("8折優(yōu)惠,機(jī)不可失,失不再來");
}
}
```
### 6. Context 商家活動類
```java
/**
* 環(huán)境類,即商家
*/
public class Context {
private String msg;
private IStrategy strategy;
public Context(IStrategy strategy, String msg){
this.strategy = strategy;
this.msg = msg;
}
public void callStrategy(){
System.out.println(this.msg);
strategy.strategy();
}
public static void main(String[] args) {
Discount dis = new Discount();
FullReduction reduction = new FullReduction();
Gif gif = new Gif();
Context context = new Context(gif,"情人節(jié)玫瑰花大促銷:");
context.callStrategy();
System.out.println();
context = new Context(reduction,"中秋節(jié)月餅大促銷:");
context.callStrategy();
System.out.println();
context = new Context(dis,"國際節(jié)家電大促銷:");
context.callStrategy();
System.out.println();
}
}
```
### 7. 運(yùn)行結(jié)果
? ![3](3.png)
## 總結(jié)
* 策略模式的優(yōu)點:
* 提供了管理相關(guān)算法足的辦法。
* 避免了難以維護(hù)的多重條件選擇語句的使用。
* 提供了可以代替繼承關(guān)系的辦法。
* 策略模式的缺點:
* 客戶端必須提前知道所有的策略類,并且自己決定使用那一個策略類。
* 策略模式造成很多的策略類。