策略模式

算法介绍:定义一系列的算法,将每一种算法封装起来,每种算法都可以互相替代,使算法能够独立与使用他的用户应用而独立变化。

商品促销结构图分析:

 

策略模式的角色:

抽象策略角色:通常由一个接口或者抽象类事项,定义了公共的方法。

具体策略角色:具体策略角色实现,包含了具体的算法和行为

上下文环境角色:上下文含有一个抽象策略角色的引用,提供给客户端程序调用,指定具体的策略角色

/**
 * @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.需要隐藏的具体的算法实现细节,多个算法之间彼此独立

 

 

 

 

 

 

 

 

 

posted @ 2019-09-23 22:44  Jemb  阅读(178)  评论(0编辑  收藏  举报