算法介绍:定义一系列的算法,将每一种算法封装起来,每种算法都可以互相替代,使算法能够独立与使用他的用户应用而独立变化。
商品促销结构图分析:
策略模式的角色:
抽象策略角色:通常由一个接口或者抽象类事项,定义了公共的方法。
具体策略角色:具体策略角色实现,包含了具体的算法和行为
上下文环境角色:上下文含有一个抽象策略角色的引用,提供给客户端程序调用,指定具体的策略角色
/** * @author bo * @Date: 2019/5/10 12:54 */ public class Client { public static void main(String[] args) { Context context = new Context(); context.setStrategy(new DiscountStrategy()); double cul = context.cul(8000); System.out.println(cul); } }
/** * @author bo * @Date: 2019/5/10 12:39 */ public interface IStrategy { /** * 真实的价格 * @param consumePrice * @return */ double realPrice(double consumePrice); }
/** * 策略上下文实现 * @author bo * @Date: 2019/5/10 12:48 */ public class Context { private IStrategy strategy; public IStrategy getStrategy() { return strategy; } public void setStrategy(IStrategy strategy) { this.strategy = strategy; } public double cul(double consumePrice){ double realPrice = this.strategy.realPrice(consumePrice); BigDecimal bd = new BigDecimal(realPrice); bd = bd.setScale(1,BigDecimal.ROUND_UP); return bd.doubleValue(); } }
/** * 具体超出部分8折商品促销策略 * @author bo * @Date: 2019/5/10 12:42 */ public class OverDiscountStrategy implements IStrategy { @Override public double realPrice(double consumePrice) { if(consumePrice > 200 ){ return 200+(consumePrice - 200) *0.8; } return consumePrice ; } }
/** * 具体满减策略 * @author bo * @Date: 2019/5/10 12:42 */ public class ReduceStrategy implements IStrategy { @Override public double realPrice(double consumePrice) { if(consumePrice >= 1000){ return consumePrice -200; } return consumePrice ; } }
/** * 具体8折策略 * @author bo * @Date: 2019/5/10 12:42 */ public class DiscountStrategy implements IStrategy { private double rate = 0; public DiscountStrategy() { this.rate = 0.8; } @Override public double realPrice(double consumePrice) { return consumePrice * this.rate; } }
涉及的原则:
1.开闭原则
2.单一职责原则:每一种算法,都是使用一个类来实现,
算法之间没有任何干扰,各个算法,都专注于自己的逻辑
不使用 策略模式的缺点
1.违反开闭原则,新增或修改策略 影响到客户端应用程序
2.将策略直接暴露给客户端,不利于封装和复用
JDK 中的应用:
ThreadPool的拒绝策略,有4中默认的拒绝策略
1.AbortPolocy默认策略:遭到拒绝直接抛出异常
2.CallerRunPolicy:不想放弃执行任务。那么就用当前的Executor进行执行,可能存在阻塞当前Executor线程,造成该线程池无法调度任务
3.DisCardPolicy:不能执行的任务直接删除
3.DiscardOldestPolicy:丢弃队列中最老的任务
相关的设计模式:
1.抽象工厂:可以切换具体的工厂或产品,而策略模式实现的是切换算法
2.状态模式:两种模式都是采用对象组合的方式,
两者的区别在于所表达的内容是不同的,状态模式切换的是状态,
当状态发生变化的时候,一定会切换委托类对象的实例
策略模式切换的是算法,算法的相互替换是 外部环境根据具体情况进行切换,
是有外部决定的
3.模板方法:让子类实现父类的部分功能 ,而策略模式是让子类
实现父类所有功能, 此部分还存在一定的争议
使用场景:
1.多个类的表现行为不同,需要运行时动态选择具体要执行的行为的时候
2.当一个类中出现了多种行为时候,需要在一个操作中进行多分只进行判断,为减少if判断的层数,可使用策略模式将分支的动作植入到策略模式的具体实现当中。
3.需要隐藏的具体的算法实现细节,多个算法之间彼此独立