设计模式之策略模式

它定义了算法家族.分别封装起来让他们可以互相替换.这个模式让算法的变化不会影响到使用算法的用户
策略模式是一种定义一系列的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不停,

简单来说策略模式就是来封装算法的,但是在实践过程中,我们发现可以使用它封装所有类的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理多变的可能性

优点:

  • 简化测试单元,因为每一个算法都有自己的类,可以通过自己的接口单独测试
  • 与简单工厂对比,只需要让客户端认识一个类(CashSuperContext.class)而简单工厂需要然后端了解具体算法对象的父类(CashSuper.class)与工厂类(CashFactory),相对而言耦合度降低

但对下面的代码而言,策略模式的缺点在于CashContext上下文中,如果需求多变的情况也是需要成本的,但是成本也是有高低的,高手与菜鸟的差距,高手可以用同样的代价获取最大的收益,或者同样的事情花最小的代价,**(书中说的…)可以使用抽象工厂进行简化,抽象工厂在后面会补充

商场促销
  1. 一下代码在抽象父类(CashSuper.class)中创建抽象方法(acceptCash),也可以说父类为抽象策略
  2. 所有子类继承父类,重写抽象方法(acceptCash),子类换言而之就是具体算法
  3. 在上下文(CashSuperContext.class)中,对具体算法进行分配
  4. 客户端只需要调用上下文(CashSuperContext.class)就可以对算法进行使用

CashSuper.class(收费父类)

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

CashRebate.class(打折子类)

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

    private double moneyRebate = 0;


    /**
     * 初始化时必须输入打折率,0.8就是八折
     * @param moneyRebate
     */
    public CashRebate(double moneyRebate) {
        this.moneyRebate = moneyRebate;
    }

    /**
     * 现金收取超类的抽象方法,收取现金
     *
     * @param money 原价金额
     * @return 返回为当前价格
     */
    @Override
    public double acceptCash(double money) {
        return money * moneyRebate;
    }
}

CashReturn.class(满减子类)

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

    private double moneyReturn;
    private double moneyCondition;

    /**
     * 初始化时必须输入返利数据
     *
     * @param moneyReturn
     * @param moneyCondition
     */
    public CashReturn(double moneyReturn, double moneyCondition) {
        this.moneyReturn = moneyReturn;
        this.moneyCondition = moneyCondition;
    }

    /**
     * 现金收取超类的抽象方法,收取现金
     *
     * @param money 原价金额
     * @return 满足返利条件进行返利,不满足返回原金额
     */
    @Override
    public double acceptCash(double money) {
        if (money >= this.moneyReturn) { //满足返利条件
           money -= moneyCondition;
        }
        return money;
    }
}

CashNormal.class(正常收费子类)

/**
 * 正常收费子类
 */
public class CashNormal extends CashSuper{

    /**
     * 正常收费类,没有任何优惠
     * @param money 原价金额
     * @return 返回原价金额
     */
    @Override
    public double acceptCash(double money) {
        return money;
    }
}

CashSuperContext.class(策略模式上下文)

/**
 * 根据策略模式修改简单工厂类
 */
public class CashSuperContext {

    private CashSuper sc;

    private double money;

    public CashSuperContext(CashSuper sc) {
        this.sc = sc;
    }

    public CashSuperContext(double money) {
        this.money = money;
    }


    public double getResult(double money) {
        return sc.acceptCash(money);
    }


    public double getReult(Integer type) {
        CashSuper sc = null;
        switch (type) {
            case 1:
                sc = new CashReturn(300, 100);
                break;
            case 2:
                sc = new CashRebate(0.95);
                break;
            default:
                sc = new CashNormal();
                break;
        }
        return sc.acceptCash(money);
    }
}

btnOk_Click.class(计算机确认按钮)

/**
 * 策略模式
 */
public class btnOk_Click {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        boolean isTrue = true;
        double sum = 0; //合计
        while (isTrue) {
            System.out.println("请输入商品金额");
            String jine = sc.nextLine();
            double jines = 0.0;
            try {
                jines = Double.valueOf(jine);
            } catch (Exception e) {
                System.out.println("非法金额数值!");
                isTrue = false;
            }
            System.out.println("请输入商品数量:");
            String numbers = sc.nextLine();
            if (numbers.matches("[0-9]*")) { //验证数量是否为正常数字
                sum += Integer.valueOf(numbers) * jines;
            } else {
                System.out.println("输入数量非法!!");
                isTrue = false;
            }
            System.out.println("当前合计金额=" + sum);
            System.out.println("结束(1)  重置(2) 继续(3)");
            String btns = sc.nextLine();
            if (btns.equals("1")) {
                //使用简单工厂模式
//                System.out.println("当前优惠服务有(1.满减,2.打折,3.无优惠):");
//                int type = Integer.valueOf(sc.nextLine());
//                CashSuper cashAccept = CashFactory.createCashAccept(type == 1 ? "满减" : type == 2 ? "打折" : "正常收费");
//                double v = cashAccept.acceptCash(sum);
//                System.out.println("最后消费金额:"+v);

                //使用策略模式
//                System.out.println("当前优惠服务有(1.满减,2.打折,3.无优惠):");
//                int type = Integer.valueOf(sc.nextLine());
//                CashSuperContext csc = null;
//                switch (type) {
//                    case 1:
//                        csc = new CashSuperContext(new CashReturn(300,100));
//                        break;
//                    case 2:
//                        csc = new CashSuperContext(new CashRebate(0.95));
//                        break;
//                    default:
//                        csc = new CashSuperContext(new CashNormal());
//                        break;
//                }
//                System.out.println("最后消费金额:"+csc.getResult(sum));

                //使用策略模式与工厂模式结合
                System.out.println("当前优惠服务有(1.满减,2.打折,3.无优惠):");
                int type = Integer.valueOf(sc.nextLine());
                CashSuperContext csc = new CashSuperContext(sum);
                System.out.println("最后消费金额:"+ csc.getReult(type));

                isTrue = false;
            } else if (btns.equals("2")) {
                sum = 0; //金额重置
                System.out.println("金额已重置当前金额为= " + sum);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值