策略模式
算法家族里面有很多的算法,封装起来,让彼此之间可以相互交替使用,使用某一个算法的用户不会受到影响,为了减少各种算法类和使用算法类之间的耦合。策略模式的应用场景:一个系统中有很多的类,区别只是行为不同。
我们接下来以一些简单案例来更好的理解
首先创建一个接口
package promotion; /** * 优惠活动 * @author lp */ public class PromotionAction { //单例模式 private PromotionStrategy promotionStrategy; public PromotionAction(PromotionStrategy promotionStrategy){ this.promotionStrategy=promotionStrategy; } /** * 执行优惠的方法 */ public void execute(){ promotionStrategy.doPromotion(); } }
然后创建执行优惠方法的类
package promotion; /** * 优惠活动 * @author lp */ public class PromotionAction { //单例模式 private PromotionStrategy promotionStrategy; public PromotionAction(PromotionStrategy promotionStrategy){ this.promotionStrategy=promotionStrategy; } /** * 执行优惠的方法 */ public void execute(){ promotionStrategy.doPromotion(); } }
分别创建不同的类实现接口模拟不同的优惠
package promotion; /** * 返现策略 * @author lp */ public class CashBackStrategy implements PromotionStrategy { @Override public void doPromotion() { System.out.println("返回现金到支付宝"); } }
package promotion; /** * 优惠券策略 * @author lp */ public class CouponStrategy implements PromotionStrategy{ @Override public void doPromotion() { System.out.println("领取优惠券打折"); } }
package promotion; /** * 没有任何优惠 */ public class EmptyStrategy implements PromotionStrategy { @Override public void doPromotion() { System.out.println("没有优惠"); } }
package promotion; /** * 团购优惠 * @author lp */ public class GroupBuyStragety implements PromotionStrategy { @Override public void doPromotion() { System.out.println("团购优惠"); } }
这是简单的实现,下面进行测试这里大家都会
/** * * 第一次测试 */ // public static void main(String[] args) { // //模拟双十一打折 // PromotionAction action1111=new PromotionAction(new GroupBuyStragety()); // //模拟618打折 // PromotionAction action618=new PromotionAction(new CouponStrategy()); // action1111.execute(); // action618.execute(); // //如果后期增加许多功能,作为程序编写人员,业务增加比较繁琐 // //如何进行优化?? // // // }
然后思考如何进行优化
可以这样来测试:
这里面的string promotionKey就是相对应的优惠的名称,根据这个名称实例化不同的优惠策略,这里用了多个else if 方便了后期增加需求,但是这样写代码还是显得十分臃肿,不够优雅。
/** * * 简单优化后测试 */ // public static void main(String[] args) { // //定义一个对象 // PromotionAction promotionAction=null; // //定义优惠的key,这里是优惠券 // String promotionKey="COUPON"; // //如果匹配的是优惠券,那就实例化优惠券的策略 // if(StringUtils.equals(promotionKey,"COUPON")){ // promotionAction=new PromotionAction(new CouponStrategy()); // //如果是返现,实例化就是返现策略 // }else if(StringUtils.equals(promotionKey,"CASHBACK")){ // promotionAction=new PromotionAction(new CashBackStrategy()); // }//。。。。不管后面有多少都是else if // promotionAction.execute(); // // }
最后一种,使用工厂单例的策略模式,创建一个工厂类
package promotion; import java.util.HashMap; import java.util.Map; /** * 促销策略工厂 * @author lp */ public class PromotionStrategyFactory { private static Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP=new HashMap<>(); static{ //优惠券 PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON,new CouponStrategy()); //返现 PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashBackStrategy()); //团购 PROMOTION_STRATEGY_MAP.put(PromotionKey.GROUPBUY,new GroupBuyStragety()); } //实例化一个没有打折的情况 private static final PromotionStrategy NON_PROMOTION=new EmptyStrategy(); //构造 private PromotionStrategyFactory(){} //根据对应的key值,实例化不同的策略 public static PromotionStrategy getPromotionStrategy(String promotionKey){ PromotionStrategy promotionStrategy=PROMOTION_STRATEGY_MAP.get(promotionKey); return promotionStrategy==null?NON_PROMOTION:promotionStrategy; } //定义接口常量,可以用枚举比较推荐 private interface PromotionKey{ String COUPON="COUPON"; String CASHBACK="CASHBACK"; String GROUPBUY="GROUPBUY"; } }
然后再看测试类如何写
public static void main(String[] args) { //策略模式:单例+工厂 这里的promotionKey,根据你定义的api常量里面选取就可以了,实现分离开来 实现了解耦,方便后期的维护增加功能等 String promotionKey="COUPON"; PromotionAction promotionAction=new PromotionAction(PromotionStrategyFactory.getPromotionStrategy(promotionKey)); promotionAction.execute(); }