一个类的行为或其算法可以在运行时更改
选择不同策略,来执行不同算法。通过注入对象,改变行为。
此模式就是spring IOC思想
事例
需求:客户在支付订单之前,可以选择一种优惠策略。优惠有两种“满100减5”和“9折”
数据结构如图:
接口及其实现类代码如下:
定义策略类,用实现类来实现具体策略
public interface Discount {
// 优惠后的实付金额。参数是优惠前的金额
float calculate(float payment);
}
public class DiscountA implements Discount {
@Override
public float calculate(float payment) {
// 按优惠策略A计算
return 95;
}
}
public class DiscountB implements Discount {
@Override
public float calculate(float payment) {
// 按优惠策略B计算
return 90;
}
}
业务类需要持有策略类,动态的注入实现类
public class ShoppingDiscount {
// 持有策略类,用set注入实现类
private Discount mDiscount;
// 注入策略
public void setDiscount(Discount discount) {
mDiscount = discount;
}
public void shop(float payment) {
// 先算优惠价再支付
float actualPayment = mDiscount.calculate(payment);
pay(actualPayment);
}
private void pay(float actualPayment) {
// 支付
}
}
测试:客户的订单100元,选择了优惠A
private void test() {
ShoppingDiscount shoppingDiscount = new ShoppingDiscount();
// 注入了优惠策略A
shoppingDiscount.setDiscount(new DiscountA());
// 假设订单价格100元
shoppingDiscount.shop(100);
}
总结
适用场景
- 一个业务有多种实现逻辑,且需要选择其中一种
- 需要动态的选择一种算法
- 需要用很多if判断语句来选择时
优点
- 策略可自由切换
- 避免了条件判断(if else)的复杂
- 扩展性高
缺点
- 策略类多
- 只能同时选中一个策略