烧烤促销--策略模式

小kim菌:菜菜,刚才我去买烧烤,满5块减2块!烧烤大叔算得手忙脚乱!

小菜菌:哈哈,买5块减2块,那买10块,减4块...

小kim菌:那买10086块呢

饥饿的小菜菌想了想,甩出一行代码。

//Math.floor:向下取整,比如Math.floor(3.5)=3, Math.floor(3.95)=3
//money/5: 总金额/满减条件,结果取整即满减倍数,再乘以满减金额,等于减的总金额
result = money - Math.floor(money/5) * 2;

小kim菌:那来个打8折呢

饥饿的小菜菌继续想...

果然,奇怪的促销增加了...

热心市民小菜菌为了支持烧烤生意,运用设计模式大法之「策略模式」,帮烧烤大叔写了个自助收银程序。不说了,上烧烤代码。

1、定义一个收银策略抽象类,并且有一个抽象方法,参数为原价,返回优惠结算价。

public abstract class CashSuper {
    public abstract double acceptCash(double money);
}

2、策略子类。

2-1)正常收费子类。

public class CashNormal extends CashSuper {
    @Override
    public double acceptCash(double money) {
        return money;
    }
}

2-2)满减策略类。

public class CashReturn extends CashSuper {
    private double moneyConditation = 0.0; //满减条件
    private double moneyReturn = 0.0; //减多少钱
    public CashReturn(double moneyConditation, double moneyReturn) {
        this.moneyConditation = moneyConditation;
        this.moneyReturn = moneyReturn;
    }
    @Override
​    public double acceptCash(double money) {
        double result = money;
        if (money > moneyConditation){
            result = money - Math.floor(money/moneyConditation) * moneyReturn;
        }
        return result;
    }
}

2-3)打折策略类。

public class CashRebate extends CashSuper{
    private double moneyRebate = 1; //折扣
    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }
    @Override
    public double acceptCash(double money) {
        return money * moneyRebate;
    }
}

3、上下文类。声明一个CashSuper对象,通过构造方法,传入具体的收费策略,根据策略获得优惠结算价。

public class CashContext {
    CashSuper cashSuper = null;
    public CashContext(String type){
        switch (type){
            case "正常收费":
                CashNormal cashNormal = new CashNormal();
                cashSuper = cashNormal;
                break;
            case "满5减2":
                CashReturn cashReturn = new CashReturn(5, 2);
                cashSuper = cashReturn;
                break;
            case "打8折":
                CashRebate cashRebate = new CashRebate(0.8);
                cashSuper = cashRebate;
                break;
        }
    }
    public double getResult(double money){
        return cashSuper.acceptCash(money);
    }
}

4、客户端类。

public class CashCount {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("-----------开始营业----------");
            System.out.println("请输入促销策略:");
            String type = scanner.next();
            CashContext context = new CashContext(type);
            System.out.println("客官,您要买多少钱烧烤呢");
            double money = scanner.nextDouble();
            double total = context.getResult(money);
            System.out.println("优惠结算价:" + total);
            System.out.println("-----------营业结束----------");
        }
    }
}

运行效果

小kim菌:😯满5减2比打8折划算耶!

小结:

1、策略模式和工厂模式区别

工厂模式是创建型模式 ,它关注对象创建,让对象的创建与具体的使用客户无关。策略模式是对象行为型模式 ,它定义了算法家族,分别封装起来,让它们之间可以切换,此模式让算法的变化,不会影响到使用算法的客户。

2、策略模式优缺点

优点:

1)定义的一系列算法完成的虽然都是相同的工作,只是实现过程不同,策略模式可以以相同的方式调用所有算法,减少了算法类与客户端类之间的耦合。

2)策略抽象类(文中的CashSuper)为Context定义了一系列可供重用的算法或行为,比如CashSuper的acceptCash,有助于析取出这些算法的公共功能。

3)策略模式遵循开闭原则,简化了单元测试,可灵活切换算法类,扩展只需增加算法类。

缺点:

1)策略算法类数量增多。

2)所有的策略都需要对外暴露,上层模块必须知道有哪些策略,然后才能知道采用哪种策略(悄悄透露:可以通过使用工厂模式、代理模式和享元模式修正,本文就是用了简单工厂模式把决策行为放到Context类,而不是放在客户端类)。

ps: 最近在学习设计模式,想通过记录故事的方式输出轻松易读的笔记。对自己是一种锻炼、成长,希望也能给学习编程的人儿带来一些些的帮助。希望自己能坚持。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值