【大话设计模式】工厂+策略+装饰模式 hw01

背景

小李已经是一个工作一年的初级工程师了,他所在的公司是一家大型购物商场。随着各种网络购物软件兴起,老板也想做一个商场的购物 APP。分给小李的是一个一个订单结算模块,需要支持各种不同的结算策略。

需求

请帮小李写一个订单结算模块,要求支持多种结算策略:

  • 原价
  • 打 X 折
  • 满减,满 X 元减 Y 元

请注意,商品有多种类型,每种类型可能会参与不同的活动,自然需要支持不同的结算策略。

任务

共三个小任务:

  • Q1:方案设计。
  • Q2:代码实现及结果截图。
  • Q3:解释为什么要用这些模式。

要求

要求如下:

  • 输入是一揽子商品,输出是最后的订单金额。
  • 至少包含两种商品,每种使用不同的结算策略,策略可任选其中一个或两个组合(比如满减 + 打折)。
  • 不要实现具体函数或方法的逻辑,可以使用 print 输出功能。

================================

类图

客户端:

import java.lang.reflect.Array;
import java.util.*;

public class Main {
    public static void main(String[] args) {


        double price = 0d;
        double totalPrice = 0d;
        double total = 0d;
        int strategy = 0;
        int num = 0;
        Scanner scanner = new Scanner(System.in);
        Integer goodCount=0;
        Integer tag = 1;
        String goods = "";


        do{
            System.out.println("---------------二、请输入商品销售模式 1.原价 2.八折 3.满300返100 4.先打8折,再满300返100 5. 先满200返50,再打7折 ---------------");
            strategy = Integer.parseInt(scanner.nextLine());
            System.out.println("---------------请输入商品单价:---------------");
            price = Double.parseDouble(scanner.nextLine());
            System.out.println("---------------请输入商品数量:---------------");
            num = Integer.parseInt(scanner.nextLine());
            System.out.println();

            if(price >0 && num>0){

                //这里就可以去写一个工厂
//                CashSuper oper = CashFactory.createCrash(discount);
//                totalPrice = oper.getCrash(price,num);

                CashContext cc = new CashContext(strategy);
                totalPrice = cc.getResult(price,num);
                total = total + totalPrice;

                System.out.println();
                System.out.println("单价:" + price + "元 数量:" + num + " 合计:" + totalPrice + "元");
                System.out.println();
                System.out.println("总计:" + total + "元");
                System.out.println();
            }

            goodCount++;
            if(goodCount>=2){
                System.out.println("是否退出?0-退出");
                tag = Integer.parseInt(scanner.nextLine());
            }

        }while(goodCount<2 && tag>0);

        System.out.println("感谢使用!");
    }
}

 CashContext:

public class CashContext {

    private ISale cs;

    public CashContext(int cashSuper){
//        this.cs = cashSuper;

//        CashSuper oper = null;
        switch (cashSuper){
            case 1:
                this.cs = new CashNormal();
                break;
            case 2:
                this.cs = new CashRebate(0.8d);
                break;
            case 3:
                this.cs = new CashReturn(300d,100d);
            case 4:
                // 先打8折,再满300返100
                CashNormal cn = new CashNormal();
                CashReturn cr1 = new CashReturn(300d,100d);
                CashRebate cr2 = new CashRebate(0.8d);

                cr1.decorate(cn);
                cr2.decorate(cr1);

                this.cs = cr2;
                break;
            case 5:
                //先满200返50,再打7折
                CashNormal cn2 = new CashNormal();
                CashRebate cr3 = new CashRebate(0.7d);
                CashReturn cr4 = new CashReturn(200d,50d);
                cr3.decorate(cn2); //用打7折算法包装基本的原价算法
                cr4.decorate(cr3); //满200返50算法装饰打7折算法
                this.cs = cr4; //将包装好的算法组合引用传递给cs对象
                break;
        }

    }

    public double getResult(double price,int num){
        return this.cs.getCrash(price,num);
    }
}

原价、打折、满减

public class CashNormal implements ISale {
    public double getCrash(double price,int num){
        return price * num;
    }
}
public class CashRebate extends CashSuper {

    private double moneyRebate = 1d;

    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }

    public double getCrash(double price,int num){
        double result =  price * num * this.moneyRebate;
        return super.getCrash(result,1);
    }

}


public class CashReturn extends CashSuper {

    private double moneyReturn = 0d;
    private double moneyCondition = 0d;

    public CashReturn(double moneyCondition,double moneyReturn){
        this.moneyReturn = moneyReturn;
        this.moneyCondition = moneyCondition;
    }

    public double getCrash(double price,int num){
        double result = price * num;
        if (moneyCondition>0 && result >= moneyCondition){
            result = result - Math.floor(result/moneyCondition) * moneyReturn;
        }
        return super.getCrash(result,1);
    }

}

定义装饰方法

public class CashSuper implements ISale{

    protected ISale component;

    public void decorate(ISale component){
        this.component = component;
    }

    public double getCrash(double price,int num){
        double result = 0d;
        if(this.component != null){
            result = this.component.getCrash(price,num);
        }
        return result;
    }

}

 接口

public interface ISale {
    public double getCrash(double price,int num);
}

为什么要用这些模式?

我的理解是简单工厂模式首先把业务逻辑抽离出来,主要是跟客户端的业务逻辑分离。

策略模式:仅仅比工厂模式多一个类,去选择使用哪一个模式。

装饰模式:它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了.

猜你喜欢

转载自blog.csdn.net/weixin_42322991/article/details/128403503
今日推荐