策略模式
參考:
- CSDN | 策略模式
- 百家號 | 策略模式
如果某個系統需要不同的算法(如超市收銀的優惠算法),那么可以把這些算法獨立出來,使之之間可以相互替換,這種模式叫做策略模式,它同樣具有三個角色:
- 環境角色:使用策略的類
- 抽象策略角色:策略共有的抽象類或接口
- 具體策略角色:具體的策略的實現
策略模式的優缺點
優點:
- 需要新的算法時,只需要拓展策略,而不需要修改原有代碼,符合開閉原則。
- 避免出現過多判斷分支,提高代碼可讀性。
- 算法間可方便的進行繼承,替換。
缺點:
- 客戶端必須熟悉所有算法,并自行決定使用哪個策略
- 策略模式將造成產生很多策略類,可以通過使用享元模式在一定程度上減少對象的數量。
適用場景
一個系統中有很多類,這些類之間只有行為表現不同時,可以使用策略模式,策略模式在實例化策略時可以配合使用簡單工廠。
例:
比如一個收銀系統,結算時有不同的優惠策略,如 九折, 五折,滿100減10等,這些不同的優惠策略便是”具體策略角色“,而收銀系統就是 ”環境角色“,還需要定義一個 ”抽象策略角色“:
package pers.junebao.strategy_mode.discount;// 抽象策略角色
public interface BaseDiscountStrategy {double preferentialAlgorithm(double money);
}
package pers.junebao.strategy_mode.discount;// 折扣優惠(具體策略角色)
public class Discount implements BaseDiscountStrategy {private double discount;public Discount(double discount) {// Discount(double discount) {if(discount > 1)discount = 1;else if(discount < 0)discount = 0.1;this.discount = discount;}@Overridepublic double preferentialAlgorithm(double money) {return money * this.discount;}
}
package pers.junebao.strategy_mode.discount;// 滿減優惠(具體策略角色)
public class FullReduction implements BaseDiscountStrategy {private double discountPrice; //優惠金額private double baseline; // 滿減條件FullReduction(double baseline, double price) {this.baseline = baseline;this.discountPrice = price;}@Overridepublic double preferentialAlgorithm(double money) {if(money >= this.baseline)money -= this.discountPrice;return money;}
}
這樣,環境角色就可以自己決定使用哪種策略而不用修改代碼了
package pers.junebao.strategy_mode;import pers.junebao.strategy_mode.discount.BaseDiscountStrategy;
import pers.junebao.strategy_mode.discount.Discount;public class CashRegisterSystem {public static void main(String[] args) {BaseDiscountStrategy ds = new Discount(0.9);double purchasingPrice = 1500;double amountsPayable = ds.preferentialAlgorithm(purchasingPrice);System.out.println(amountsPayable);}
}
對于這些具體策略,可以使用簡單工廠,進一步屏蔽策略的具體細節
package pers.junebao.strategy_mode.discount;public class StrategyFactory {public static BaseDiscountStrategy getDiscountStrategy(String name) {BaseDiscountStrategy result = null;switch (name){case "九折":{result = new Discount(0.9);break;}case "五折": {result = new Discount(0.5);break;}case "滿100減10": {result = new FullReduction(100, 10);break;}case "滿1000減200": {result = new FullReduction(1000, 200);break;}default:result = new OriginalPrice();}return result;}
}
BaseDiscountStrategy ds = StrategyFactory.getDiscountStrategy("滿1000減200");
GitHub | 完整代碼