一、策略模式:
  如果说简单工厂模式对对象分类,
  那么策略模式就是对相似逻辑算法分类,
  将算法的切换变成一个目标可变的行为,
  由策略决定行为。

二、基本思路:
  1.创建策略抽象类,定义所有支持的算法的公共接口;
  2.继承抽象类,策略具体化;
  3.定义Context类作为上下文承接的角色,是使用了某种策略的类,通过策略改变自身行为。

三、简单样例:
  以简单收银软件为例,灵活解决原价、打折、返现、返积分等问题。
/**
 * 策略抽象类
 * 定义收费抽象方法
 */
 abstract class CashSuper{
    public abstract double acceptCash(double money);
}
/**
 * 具体策略的实现
 * 将收费方式具体化,例如按照原价,或者打折或者满价返现等等
 */
//正常收费
class CashNormal extends CashSuper{
    @Override
    public double acceptCash(double money) {
        return money;
    }
}

//打折收费
class CashRebate extends CashSuper{
     private double cashRebate=1;
     CashRebate(double moneyRebate){//传入折扣率,之前初始化为1
         this.cashRebate=moneyRebate;
     }

    @Override
    public double acceptCash(double money) {
        return money*cashRebate;//折扣后
    }
}

//收费返利
class CashReturn extends CashSuper{
     private double cashCondition=0;
     private double cashReturn=0;

     //满cashCondition,送cashReturn
     CashReturn(double cashCondition, double cashReturn){
         this.cashCondition=cashCondition;
         this.cashReturn=cashReturn;
     }

    @Override
    public double acceptCash(double money) {
         double result=money;
         if (money>=cashCondition){
             result=money-Math.floor(money/cashCondition)*cashReturn;
         }
        return result;
    }
}
/**
 * 接收具体策略,并产生不同的行为
 * 根据收费策略,决定费用计算方法
 */
class Context{
    private CashSuper cashSuper;

    //通过构造方法传入具体的收费策略
    public Context(CashSuper cashSuper){
        this.cashSuper=cashSuper;
    }

    public double getResult(double price){
        //根据收费策略的不同,用不同的计算方法获得具体收费金额。
        return cashSuper.acceptCash(price);
    }
}
/**
 * 选择策略
 * 客户端选择收费方法,即可得到响应的结果,
 * 具体算法已经跟客户程序隔离
 */
class Main{

    public static Context chooseStrategy(String type){
        Context context=null;
        //根据收费类型不同,将相应的策略对象传入Context中,
        // 之后Context将产生对应行为,最终得出结果
        switch (type) {
            case "正常收费":
                context = new Context(new CashNormal());
                break;
            case "打8折":
                context = new Context(new CashRebate(0.8));
                break;
            case "满300返100":
                context = new Context(new CashReturn(300, 100));
                break;
            default:
                break;
        }
        return context;
    }
    public static void main(String[] args) {
        double single=12;//单价
        double num=3;//数量
        double totalPrice=0;//总价

        Context context=null;
        String[] types={"正常收费","打8折","满300返100"};
        context=chooseStrategy(types[1]);

        //进行计算
        totalPrice=context.getResult(single*num);
        System.out.println("应收费:"+totalPrice);
    }
}