Java策略模式
1.策略模式簡介
策略模式:策略模式是一種行為型模式,它將物件和行為分開,將行為定義為 一個行為介面
和 具體行為的實現
。策略模式最大的特點是行為的變化,行為之間可以相互替換。每個if判斷都可以理解為就是一個策略。本模式使得演算法可獨立於使用它的使用者而變化
2.模式結構
策略模式包含如下角色:
-
Strategy: 抽象策略類:策略是一個介面,該介面定義若干個演算法標識,即定義了若干個抽象方法(如下圖的algorithm())
-
Context: 環境類 /上下文類:
- 上下文是
依賴
於介面的類(是面向策略設計的類,如下圖Context類),即上下文包含用策略(介面)宣告的變數
(如下圖的strategy成員變數)。 - 上下文
提供一個方法
(如下圖Context類中的的lookAlgorithm()方法),該方法委託策略變數呼叫具體策略所實現的策略介面中的方法
(實現介面的類重寫策略(介面)中的方法,來完成具體功能)
- 上下文是
-
ConcreteStrategy: 具體策略類:具體策略是實現策略介面的類(如下圖的ConcreteStrategyA類和ConcreteStrategyB類)。具體策略實現策略介面所定義的抽象方法,即給出演算法標識的具體方法。(說白了就是重寫策略類的方法!)
3.案例
1).傳統實現方式
程式碼
public Double calculationPrice(String type, Double originalPrice, int n) {
//中級會員計費
if (type.equals("intermediateMember")) {
return originalPrice * n - originalPrice * 0.1;
}
//高階會員計費
if (type.equals("advancePrimaryMember")) {
return originalPrice * n - originalPrice * 0.2;
}
//普通會員計費
return originalPrice;
}
傳統的實現方式,通過傳統if程式碼判斷。這樣就會導致後期的維護性非常差。當後期需要新增計費方式,還需要在這裡再加上if(),也不符合設計模式的開閉原則。
2).策略模式實現
抽象類策略
package StrategyExercise;
public interface MemberStrategy {
// 一個計算價格的抽象方法
//price商品的價格 n商品的個數
public double calcPrice(double price, int n);
}
具體實現類
// 普通會員——不打折
public class PrimaryMemberStrategy implements MemberStrategy { // 實現策略
//重寫策略方法具體實現功能
@Override
public double calcPrice(double price, int n) {
return price * n;
}
}
package StrategyExercise;
// 中級會員 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = (price * n) - price * n * 0.1;
return money;
}
}
package StrategyExercise;
// 高階會員類 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = price * n - price * n * 0.2;
return money;
}
}
上下文類
也叫做上下文類或環境類,起承上啟下封裝作用。
package StrategyExercise;
/**
* 負責和具體的策略類互動
* 這樣的話,具體的演算法和直接的客戶端呼叫分離了,使得演算法可以獨立於客戶端獨立的變化。
*/
// 上下文類/環境類
public class MemberContext {
// 使用者折扣策略介面
private MemberStrategy memberStrategy;
// 注入構造方法
public MemberContext(MemberStrategy memberStrategy) {
this.memberStrategy = memberStrategy;
}
// 計算價格
public double qoutePrice(double goodsPrice, int n){
// 通過介面變數呼叫對應的具體策略
return memberStrategy.calcPrice(goodsPrice, n);
}
}
測試類
package StrategyExercise;
// 測試類
public class Application {
public static void main(String[] args) {
// 具體行為策略
MemberStrategy primaryMemberStrategy = new PrimaryMemberStrategy(); // 介面回撥(向上轉型)
MemberStrategy intermediateMemberStrategy = new IntermediateMemberStrategy();
MemberStrategy advanceMemberStrategy = new AdvanceMemberStrategy();
// 使用者選擇不同策略
MemberContext primaryContext = new MemberContext(primaryMemberStrategy);
MemberContext intermediateContext = new MemberContext(intermediateMemberStrategy);
MemberContext advanceContext = new MemberContext(advanceMemberStrategy);
//計算一本300塊錢的書
System.out.println("普通會員的價格:"+ primaryContext.qoutePrice(300,1));// 普通會員:300
System.out.println("中級會員的價格:"+ intermediateContext.qoutePrice(300,1));// 中級會員 270
System.out.println("高階會員的價格:"+ advanceContext.qoutePrice(300,1));// 高階會員240
}
}
執行結果
普通會員的價格:300.0
中級會員的價格:270.0
高階會員的價格:240.0
上述案例UML類圖
4.策略模式優缺點
1)優點
-
策略模式提供了對“開閉原則”的完美支援,使用者可以在不 修改原有系統的基礎上選擇演算法或行為,也可以靈活地增加 新的演算法或行為。
-
策略模式提供了管理相關的演算法族的辦法。
-
策略模式提供了可以替換繼承關係的辦法。
-
使用策略模式可以避免使用多重條件轉移語句。
2)缺點
- 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。
- 策略模式將造成產生很多策略類,可以通過使用享元模式在一 定程度上減少物件的數量。
5.策略模式適用場景
在以下情況下可以使用策略模式:
- 如果在一個系統裡面有許多類,它們之間的區別僅在於它們 的行為,那麼使用策略模式可以動態地讓一個物件在許多行 為中選擇一種行為。
- 一個系統需要動態地在幾種演算法中選擇一種。
- 如果一個物件有很多的行為,如果不用恰當的模式,這些行 為就只好使用多重的條件選擇語句來實現。
- 不希望客戶端知道複雜的、與演算法相關的資料結構,在具體 策略類中封裝演算法和相關的資料結構,提高演算法的保密性與 安全性。
在我們生活中比較常見的應用模式有:
1、電商網站支付方式,一般分為銀聯、微信、支付寶,可以採用策略模式
2、電商網站活動方式,一般分為滿減送、限時折扣、包郵活動,拼團等可以採用策略模式
6.總結
• 在策略模式中定義了一系列演算法,將每一個演算法封裝起來,並讓它們 可以相互替換。策略模式讓演算法獨立於使用它的客戶而變化,也稱為 政策模式。策略模式是一種物件行為型模式。
• 策略模式包含三個角色:環境類
在解決某個問題時可以採用多種策略, 在環境類中維護一個對抽象策略類的引用例項;抽象策略類
為所支援 的演算法宣告瞭抽象方法,是所有策略類的父類;具體策略類
實現了在 抽象策略類中定義的演算法。
• 策略模式是對演算法的封裝,它把演算法的責任和演算法本身分割開,委派 給不同的物件管理。策略模式通常把一個系列的演算法封裝到一系列的 策略類裡面,作為一個抽象策略類的子類。
• 策略模式主要優點在於對“開閉原則”的完美支援,在不修改原有系 統的基礎上可以更換演算法或者增加新的演算法
,它很好地管理演算法族, 提高了程式碼的複用性,是一種替換繼承,避免多重條件轉移語句的 實現方式;其缺點在於客戶端必須知道所有的策略類,並理解其區 別,同時在一定程度上增加了系統中類的個數,可能會存在很多策 略類
。
• 策略模式適用情況包括:在一個系統裡面有許多類,它們之間的區 別僅在於它們的行為,使用策略模式可以動態地讓一個物件在許多 行為中選擇一種行為;一個系統需要動態地在幾種演算法中選擇一種; 避免使用難以維護的多重條件選擇語句;希望在具體策略類中封裝 演算法和與相關的資料結構。
注:如果文章有任何錯誤或不足,請各位大佬盡情指出,評論留言留下您寶貴的建議!如果這篇文章對你有些許幫助,希望可愛親切的您點個贊推薦一手,非常感謝啦