簡介
策略模式屬於用處很多並且很簡單的一種設計模式
在策略模式(Strategy Pattern)中,一個類的行為或其演算法可以在執行時更改。這種型別的設計模式屬於行為型模式。
策略模式中定義了演算法家族,分別封裝起來,讓他們之間可以相互替換,此模式讓演算法的變化,不會影響到使用演算法的客戶。
場景描述
我們再來假設一個場景,根據不同的下訂單入口對使用者進行積分獎勵
app下單使用者 | web下單使用者 | 小程式下單使用者 |
---|---|---|
獎勵100積分 | 獎勵20積分 | 獎勵50積分 |
壞程式碼
package design.pattern.reward;
public class Reward {
/**
* 下單平臺 0 web 1 小程式 2 app
*/
private int platform = 0;
public Reward(int platform) {
this.platform = platform;
}
/**
* 給使用者送積分
*/
public void giveScore() {
int score = 0;
switch (platform) {
case 0: //web
//todo
score = 20;
break;
case 1: //小程式
//todo
score = 50;
break;
case 2: //app
//todo
score = 100;
break;
}
System.out.println("送給使用者" + score + "分");
}
}
複製程式碼
業務呼叫:
package design.pattern.reward;
public class PayNotify {
public static void main(String[] args) {
Reward reward = new Reward(2);
reward.giveScore();
}
}
複製程式碼
當我們的演算法越來越多,越來越複雜的時候,並且當某個演算法發生變化,將對所有其他計算方式都會產生影響,不能有效的彈性、清晰的擴充,所以這個時候我們的策略模式就上場了。
策略模式UML圖(畫圖工具不工作了)
策略模式實現
1.首先介面宣告-抽象策略
package design.pattern.reward.score;
public interface InterfaceScore {
/**
* 送積分
*/
public void giveScore();
}
複製程式碼
2.我們實現介面的giveScore方法-實現具體策略演算法
app端積分
package design.pattern.reward.score;
public class AppScore implements InterfaceScore {
private int score = 100;
/**
* 送積分
*/
public void giveScore() {
//todo 具體演算法邏輯
System.out.println("送你積分" + score);
}
}
複製程式碼
web端積分:
package design.pattern.reward.score;
public class WebScore implements InterfaceScore {
private int score = 20;
/**
* 送積分
*/
public void giveScore() {
//todo 具體演算法邏輯
System.out.println("送你積分" + score);
}
}
複製程式碼
- 不同策略演算法排程類
package design.pattern.reward;
import design.pattern.reward.score.InterfaceScore;
public class Context {
private InterfaceScore scoreObj;
public Context(InterfaceScore algorithmObj) {
this.scoreObj = algorithmObj;
}
public void giveScore() {
this.scoreObj.giveScore();
}
}
複製程式碼
- 客戶端呼叫
Context context1 = new Context(new AppScore());
context1.giveScore();
Context context2 = new Context(new WebScore());
context2.giveScore();
複製程式碼
output:
送你積分100
送你積分20
複製程式碼
好像跟我們剛開始的呼叫方法不一樣,約定好的是傳一個type值來確定計算的方法,現在直接將計算規則方法暴露給了呼叫方
繼續改造 策略模式+簡單工廠
package design.pattern.reward;
import design.pattern.reward.score.AppScore;
import design.pattern.reward.score.InterfaceScore;
import design.pattern.reward.score.WebScore;
public class Context {
private InterfaceScore scoreObj;
public Context(int platform) {
switch (platform) {
case 0: //web
this.scoreObj = new WebScore();
break;
case 1: //小程式
//todo
break;
case 2: //app
this.scoreObj = new AppScore();
break;
}
}
public void giveScore() {
this.scoreObj.giveScore();
}
}
複製程式碼
呼叫:
Context context1 = new Context(0);
context1.giveScore();
Context context2 = new Context(2);
context2.giveScore();
複製程式碼
是不是很簡單。。。
總結:
策略模式是一種定義一系列演算法的方法,從概念上來看,所有這些演算法完成的都是相同的工作,只是實現不同,他可以以相同的方式呼叫所有的演算法.減少了演算法與使用演算法之間的耦合.
策略模式是用來封裝演算法的,但在實踐中我們可以用它來封裝幾乎任何型別的規則, 只要在分析過程中需要在不同時間應用不同的業務規則,就可以考慮使用策略模式處理這種變化的可能性。
和上次講到的模版方法模式差異
模版方法模式使用了繼承方式實現演算法,而策略模式使用了組合方式 模版方法模式對於演算法擁有絕對的控制,而策略模式不對演算法控制 模版方法的依賴程度要比策略模式高 。。。。。
更多精彩內容關注呆呆公眾號: