1 定义
策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
简单来说就是就定义一个策略接口,子类策略去实现该接口去定义不同的策略。然后定义一个环境(Context,也就是需要用到策略的对象)类,以策略接口作为成员变量,根据环境来使用具体的策略。
简单说就是一个公共的抽象方法不同的子类实现,之后根据需求选择不同的方法
1.1 优点
1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。
1.2 缺点:
1、策略类会增多。
2、所有策略类都需要对外暴露。
2 策略模式实战
案例:结算价格计算,根据Vip不同等级进行运算
2.1 不同VIP优惠价格分析
用户在购买商品的时候,很多时候会根据Vip等级打不同折扣,尤其是在线商城中体现的淋漓尽致。我们这里也基于
真实电商案例来实现VIP等级价格制:
Vip0->普通价格
Vip1->减5元
Vip2->7折
Vip3->5折
2.2 代码实现
定义策略接口: Strategy
public interface Strategy { //价格计算 Integer payMoney(Integer payMoney); }
定义Vip0策略: StrategyVipOne
@Component(value = "strategyVipOne") public class StrategyVipOne implements Strategy { //普通会员,没有优惠 @Override public Integer payMoney(Integer payMoney) { return payMoney; } }
定义Vip1策略: StrategyVipTwo
@Component(value = "strategyVipTwo") public class StrategyVipTwo implements Strategy{ //策略2 @Override public Integer payMoney(Integer payMoney) { return payMoney-5; } }
定义Vip2策略: StrategyVipThree
@Component(value = "strategyVipThree") public class StrategyVipThree implements Strategy{ //策略3 @Override public Integer payMoney(Integer payMoney) { return (int)(payMoney*0.7); } }
定义Vip3策略: StrategyVipFour
@Component(value = "strategyVipFour") public class StrategyVipFour implements Strategy{ //策略4 @Override public Integer payMoney(Integer payMoney) { return (int)(payMoney*0.5); } }
定义策略工厂: 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,将如下策略配置进去
#策略配置
strategy: strategyMap: 1: strategyVipOne 2: strategyVipTwo 3: strategyVipThree 4: strategyVipFour
等级控制:修改 UserHandler 添加等级属性
修改 UserHandlerShare 定义等级,代码如下:
装饰者模式中修改 VipMoneySum 的价格运算,代码如下:
测试:
3 完整代码
OrderMoney.java
import org.omg.CORBA.INTERNAL; /***** * @Author: oldlu * @Description: com.oldlu.strategy.OrderMoney ****/ public class OrderMoney { //将策略接口作为属性 private Strategy strategy; public void setStrategy(Strategy strategy) { this.strategy = strategy; } //价格计算 public Integer moneySum(Integer money){ return strategy.money(money); } }
Strategy.java
public interface Strategy { //金额计算 Integer money(Integer money); }
StrategyFactory.java
import java.util.HashMap; import java.util.Map; /***** * @Author: oldlu * @Description: com.oldlu.strategy.StrategyFactory ****/ public class StrategyFactory { //定义一个Map对象存储所有策略 private static Map<Integer,Strategy> strategyMap = new HashMap<Integer, Strategy>(); //初始化所有策略并存入到Map中 static { strategyMap.put(1,new Vip1()); strategyMap.put(2,new Vip2()); strategyMap.put(3,new Vip3()); } //对外提供一个方法用于根据用户提供的等级获取指定策略 public static Strategy get(Integer level){ return strategyMap.get(level); } }
StrategyTest.java
/***** * @Author: oldlu * @Description: com.oldlu.strategy.StrategyTest ****/ public class StrategyTest { public static void main(String[] args) { //创建对象实例 OrderMoney orderMoney = new OrderMoney(); //获取指定策略 Strategy strategy = StrategyFactory.get(3); //设置策略 orderMoney.setStrategy(strategy); //执行计算[基于不同策略计算] Integer money = orderMoney.moneySum(1000); System.out.println(money); } }
Vip1.java
/***** * @Author: oldlu * @Description: com.oldlu.strategy.Vip1 ****/ public class Vip1 implements Strategy { //Vip1 用户 @Override public Integer money(Integer money) { return money; } }
Vip2.java
/***** * @Author: oldlu * @Description: com.oldlu.strategy.Vip1 ****/ public class Vip2 implements Strategy { //Vip2 用户 @Override public Integer money(Integer money) { return money-5; } }
Vip3.java
/***** * @Author: oldlu * @Description: com.oldlu.strategy.Vip1 ****/ public class Vip3 implements Strategy { //Vip3 用户 @Override public Integer money(Integer money) { return (int)(money*0.5); } }