大话设计模式读书笔记系列-2.策略模式

>>>大话设计模式读书笔记系列目录>>>

策略模式html

它定义了算法家族,分别封装起来,让他们之间能够互相转换,此模式让算法的变化,不会影响到使用算法的客户算法

 

场景:设计模式

商场售卖商品的时候针对不一样场景指定不一样的折扣策略(原价消费/折扣消费/返利消费),经过构建不一样的对象来实现不一样策略切换.ide

 

收费抽象类
/**
 * 现金收费抽象类
 */
public abstract class CashSuper {
    /**
     * 现金收取超类的抽象方法,收取现金
     * @param money 原价
     * @return 当前价
     */
    public abstract double acceptCash(double money);
}

 

收费子类
/**
 * 正常收费子类
 */
public class CashNormal extends CashSuper {
    @Override
    public double acceptCash(double money) {
        return money;//正常原价返回
    }
}

/**
 * 打折收费子类
 */
public class CashRebate extends CashSuper {

    /**
     * 费率
     */
    private double moneyRebate = 1d;

    /**
     * 打折收费,初始化时,必须输入折扣率,如八折,就是0.8
     *
     * @param moneyRebate
     */
    public CashRebate(String moneyRebate) {
        this.moneyRebate = Double.valueOf(moneyRebate);
    }

    @Override
    public double acceptCash(double money) {
        return money * this.moneyRebate;
    }
}

/**
 * 返利收费子类
 */
public class CashReturn extends CashSuper {

    /**
     * 返利条件,即知足X元
     */
    private double moneyCondition = 0.0d;
    /**
     * 返利金额,即知足条件之后返还X元
     */
    private double moneyReturn = 0.0d;

    /**
     * 返利收费,初始化时必须输入返利条件和返利金额,好比满300元减100元,则moneyCondition=300,moneyReturn=100
     *
     * @param moneyCondition 返利条件
     * @param moneyReturn    返利金额
     */
    public CashReturn(String moneyCondition, String moneyReturn) {
        this.moneyCondition = Double.valueOf(moneyCondition);
        this.moneyReturn = Double.valueOf(moneyReturn);
    }

    @Override
    public double acceptCash(double money) {
        double result = money;
        //若消费金额大于返利条件就进行返利计算
        if (money > this.moneyCondition) {
            //结果=总消费金额-(总金额整除返利条件)*返还金额,例如消费910元,610=910-(910/300)*100
            result = money - (int) Math.floor(money/this.moneyCondition) * this.moneyReturn;
        }
        return result;
    }
}

 

策略上下文类
/**
 * 策略上下文类
 */
public class CashContext {

    /**
     * 策略
     */
    private CashSuper cs;

    /**
     * 初始化要使用的策略
     *
     * @param cSuper
     */
    public CashContext(CashSuper cSuper) {
        this.cs = cSuper;
    }

    /**
     * 得到计算结果
     *
     * @param money
     */
    public double GetResult(String money) {
        return this.cs.acceptCash(Double.valueOf(money));
    }
}

 

调用端post

public class StrategyPatternDemo {
    public static void main(String[] args) {
        //返回结果
        double total = 0.0d;
        //采用正常收费策略
        total = new CashContext(new CashNormal()).GetResult("910");
        System.out.println("采用正常收费策略:" + total);
        //采用打折收费策略
        total = new CashContext(new CashRebate("0.8")).GetResult("910");
        System.out.println("采用打折收费策略:" + total);
        //采用返利收费策略
        total = new CashContext(new CashReturn("300", "100")).GetResult("910");
        System.out.println("采用返利收费策略:" + total);
    }
}

 

结果单元测试

采用正常收费策略:910.0
采用打折收费策略:728.0
采用返利收费策略:610.0

 

解析:测试

1.策略模式是一种定义一系列算法的方法,从概念上来看,全部这些算法完成的都是相同的工做,只是实现不一样,他能够以相同的方式调用全部的算法,减小了各类算法类与使用算法类之间的耦合.this

2.策略模式的<CashSuper>类层次为<CashContext>定义了一系列的可重用的算法或行为.继承有助于析取出这些算法中的公共功能.url

3.策略模式的优势是简化了单元测试,由于每一个算法都有本身的类,能够经过本身的接口单独测试.spa

4.当不一样的行为堆砌再一个类中时,很难避免使用条件语句来进行选择合适的行为,将这些行为封装在一个个独立的<CashSuper>中,能够在使用这些行为的类中消除条件语句.

5.策略模式就是用来封装算法的,但在实践中,咱们发现能够用他来封装几乎任何类型的规则,只要在分析过程当中听到须要再不一样时间应用不一样的业务规则,就能够考虑使用策略模式出来这种变化的可能性.

6.基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转发给策略模式的<CashContext>对象.

相关文章
相关标签/搜索