策略模式
参考:
- 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 | 完整代码