策略模式
定义:策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。
简单来说就是就定义一个策略接口,子类策略去实现该接口去定义不同的策略。然后定义一个环境(Context,也就是需要用到策略的对象)类,以策略接口作为成员变量,根据环境来使用具体的策略。
优点:
1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。
缺点:
1、策略类会增多。
2、所有策略类都需要对外暴露。
使用场景
-
多个类只有算法或行为上稍有不同的场景
-
算法需要自由切换的场景
-
需要屏蔽算法规则的场景
应用实例
- 出行方式,自行车、汽车等,每一种出行方式都是一个策略
- 商场促销方式,打折、满减等
电商系统中的应用:结算价格计算,根据Vip不同等级进行运算
Vip1->原价格
Vip2->减5元
Vip3->7折
具体的代码实现:
定义策略接口: Strategy
public interface Strategy {
//价格计算
Integer payMoney(Integer payMoney);
}
定义Vip1策略: StrategyVipOne
@Component(value = "strategyVipOne")
public class StrategyVipOne implements Strategy {
//普通会员,没有优惠
@Override
public Integer payMoney(Integer payMoney) {
return payMoney;
}
}
定义Vip2策略: StrategyVipTwo
@Component(value = "strategyVipTwo")
public class StrategyVipTwo implements Strategy{
//策略2
@Override
public Integer payMoney(Integer payMoney) {
return payMoney-5;
}
}
定义Vip3策略: StrategyVipThree
@Component(value = "strategyVipThree")
public class StrategyVipTwo implements Strategy{
//策略2
@Override
public Integer payMoney(Integer payMoney) {
return (int)payMoney*0.7;
}
}
定义策略工厂: StrategyFactory
@Data
@ConfigurationProperties(prefix = "strategy")
@Component
public class StrategyFactory implements ApplicationContextAware {
//ApplicationContext
//1、定义一个Map存储所有策略【strategyVipOne=instanceOne】
// 【strategyVipTwo=instanceTwo】
private ApplicationContext act;
//定义一个Map,存储等级和策略的关系,通过application.yml配置注入进来
private Map<Integer,String> strategyMap;
//3、根据会员等级获取策略【1】【2】【3】
public Strategy getStrategy(Integer level){
//根据等级获取策略ID
String id = strategyMap.get(level);
//根据ID获取对应实例
return act.getBean(id,Strategy.class);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws
BeansException {
act=applicationContext;
}
}
修改application.yml,增加VIP等级与beanId的映射
#策略配置
strategy:
strategyMap:
1: strategyVipOne
2: strategyVipTwo
3: strategyVipThree
// 注入策略工厂
@Autowired
private StrategyFactory strategyFactory;
// 用户共享信息
@Autowired
private ThreadUserLog threadUserLog;
//Vip价格根据等级优惠
private void vipMoneySum(Order order){
// 获取优惠策略
Strategy strategy = strategyFactory.getStrategy(threadUserLog.get().getLevel());
// 价格计算
order.setPaymoney(strategy .payMoney(order.getPaymoney()));
}