工作中的設計模式 —— 策略模式
前言
策略模式是一種行為設計模式,它能讓你定義一系列演算法,並將每種演算法分別放入獨立的類中,以使演算法的對象能夠相互替換。
使用場景
策略模式在工作中使用的相對是比較多的,像支付場景,計費場景,優惠場景,活動獎勵、用戶等級等等。
當然也有很多直白的說法,就是替換一大堆的 if else。
if (x == aaa) {
// 200 行程式碼
} else if (x == bbb) {
// 200 行程式碼
} else if (x == ccc) {
// 200 行程式碼
}
按照上面的 if else 邏輯,其中 aaa、bbb、ccc 就是不同的策略。而使用策略模式的目的,就是當又增加了 ddd、eee 等等的時候,更方便的擴展。
這裡以工作中遇到的場景舉例:
這裡選擇使用理財儲蓄場景中的計費策略舉例:
在理財儲蓄場景中,需要每日給用戶發放利息,同時用戶分為普通用戶、持卡用戶,他們有分別的利率以及計息方式。
很明顯,在計費時要使用策略模式,按照以下模式進行開發。
使用方式
定義計算介面
public interface RevenueCalculator {
RevenueDTO calculate(BigDecimal asset);
}
定義不同的計算實現
對外暴露的是一個介面,而具體的實現,則需要自己去擴展。下面展示了三個實現。
@Component
public class DefaultRevenueCalculator implements RevenueCalculator {
@Override
public RevenueDTO calculate(BigDecimal asset) {
return null;
}
}
@Component
public class StepRateGeneralRevenueCalculator implements RevenueCalculator {
@Override
public RevenueDTO calculate(BigDecimal asset) {
return null;
}
}
@Component
public class StepRateHoldCardRevenueCalculator implements RevenueCalculator {
@Override
public RevenueDTO calculate(BigDecimal asset) {
return null;
}
}
當然這裡 StepRateHoldCardRevenueCalculator 和 StepRateGeneralRevenueCalculator 有抽象相同的業務邏輯,也可以抽出來一層工廠方法。
這些在這裡都不是重點。
通過實現介面的方式,在後面有新的計費策略時,就寫一個新的實現類就可以了。
現在的問題是,我如何確定哪個用戶走那一套策略呢?
策略類
public enum UserTypeEnum implements BaseEnum {
/**
* OWealth 原始計息方式
*/
DEFAULT_USER(-1, "原計息方式", "defaultRevenueCalculator"),
/**
* 普通用戶
*/
GENERAL_USER(0, "默認用戶", "stepRateGeneralRevenueCalculator"),
/**
* 持卡用戶
*/
HOLD_CARD_USER(1, "持卡用戶", "stepRateHoldCardRevenueCalculator"),
;
// 省略程式碼
}
public class RevenueCalculatorFactory {
public static RevenueCalculator getCalculator(UserTypeEnum userType) {
return SpringContextHolder.getBean(userType.getServiceName());
}
}
這裡只是介紹了使用枚舉維護用戶類型和策略實現的關係,也可以在這裡面寫 if else 判斷策略,或者維護在資料庫中。
總結
本文介紹了在工作中使用策略模式,總結一下經常使用到的場景:
- 支付方式的選擇:微信、支付寶、銀聯等等
- 計費策略不同:不同的用戶計費方式不同(收費/運費等)
- 活動規則選擇:不同的活動走不同計算的邏輯
- 計息方式不同:不同的用戶(產品)計算利息的方式不同
…
更多的就需要小夥伴去發現和總結了。
漁、就在這裡,能不能打到魚,那就靠耐心了。
加油