设计模式之策略模式(札记)

设计模式之策略模式(笔记)

策略模式:它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。
策略模式封装了变化,减少了各种算法类与使用算法类之间的耦合。
例如做一个商场收银软件,定义三种收费方式,正常收费,打8折,满300送100.这三种收费方式实际上就是具体的三种策略方式。
首先定义一个抽象算法类CashSuper,定义支持所有算法的公共接口

public abstract class CashSuper {
   //应付金额抽象方法
    public abstract double acceptCash(double money);
}

接着定义三种具体的策略类,来继承CashSuper
正常收费类 CashNormal

public class CashNormal extends CashSuper {

    @Override
    public double acceptCash(double money) {

        return money;
    }
}

打折收费类CashRebate

public  class CashRebate extends CashSuper {

    private double moneyRebate=1;
    //折扣
    public CashRebate(String rebate){
        this.moneyRebate=Double.valueOf(moneyRebate);
    }

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

返回收费类CashReturn

public class CashReturn extends CashSuper{
    private double moneyCondition=0;
    private double moneyReturn=0;

    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>=moneyCondition){
            result=money-Math.floor(money/moneyCondition)*moneyReturn;
        }
        return result;
    }

}

定义一个CashContext类来配置,用来维护一个对CashSuper抽象类的应用

public class CashContext {

     private CashSuper cashSuper;
     //带type的构造函数,将实例化具体策略的过程由客户端转移到cashcontext类中,结合了简单工厂的应用
     public CashContext(String type){
         switch (type) {
        case "正常收费":
            CashNormal cNormal=new CashNormal();
            cashSuper=cNormal;
            break;
        case "打8折":
            CashRebate cRebate=new CashRebate("0.8");
            cashSuper=cRebate;
            break;
        case "满300送100":
            CashReturn cReturn=new CashReturn("300","100");
            cashSuper=cReturn;
            break;

        }
     }
     //返回应付金额
     public double getResult(double money){
         return cashSuper.acceptCash(money);
     }
}