第二次博客作业-航空货运管理系统

一、前言

此次迭代的题目较上一次电梯迭代的题目难度较小,我更加得心应手。不过在处理这道题目的时候,我同样遇到了很多的小问题,这类小问题是一道题写出来的关键。本次题目集主要考察的是继承与多态,涉及的知识点有接口、抽象类,以及各种原则的使用,如单一职责原则、开闭原则、依赖倒置原则、里氏代换原则等等。

二、设计与分析

1.第一次“航空货运管理系统”分析

1.1题目要求

某航空公司“航空货运管理系统”中的空运费的计算涉及多个因素,通常包括货物重量/体积、运输距离、附加费用、货物类型、客户类型以及市场供需等。题目要求我们计算“计费重量”、“基础运费”等,以及根据航空公司提供的信息,按照一定格式输出。 这不仅考验我们对业务逻辑的理解与把握,更要求我们能够运用所学的编程知识,将这些复杂的规则转化为准确、高效的代码实现。

1.2类图

本次设计中共包含十个类,它们各自承担着独特的职责,共同构建起系统的基本架构:BasicInformation、BasicInformation2、Customer、Sender、Addressee、AbstractGoods、Goods、Flight、Order、Main;

BasicInformation:用于存储基本的数据,是Customer的父类

Customer:用于存储顾客信息的类

Sender:用于存储发件人信息的类

Addressee:用于存储收件人信息的类

Goods:用于存储货物信息的类

Flight:用于存储航班信息的类

Order:用于存储订单信息的类

Main:主类

1.3SourceMonitor分析结果:


1.4分析

通过 SourceMonitor 工具对代码进行分析,我们获取了一系列关键数据:
代码复杂度:平均复杂度为 1.11,最大复杂度为 4(位于Goods.calculateRate()方法) ,说明整体代码逻辑复杂程度不算很高,但部分方法存在一定复杂性。平均块深度为 1.44,最大块深度为 3 ,反映代码中嵌套结构的深度情况。

复杂方法分布:图中列出了最复杂的方法,如Goods.calculateRate()复杂度为 4 ,有 8 条语句,调用深度为 2 ,调用次数为 1 。说明该方法内部逻辑相对复杂,可能包含较多条件判断或计算逻辑。

语句情况:共有 150 条语句,分支语句占比 2.7% ,方法调用语句有 24 条 。分支语句占比低,说明代码中条件判断逻辑不算多;方法调用语句数量表明代码中存在一定的方法间调用关系。

注释情况:带注释的行数占比为 20.0% ,这是比较严重的问题,缺乏注释会使代码可读性变差,后期维护和理解代码困难。

1.5心得

将深度较大的方法进行拆分:有部分方法的深度较大,最好将其进行拆分

添加注释:我应该增加些注释,方便后期的维护

2.第二次“航空货运管理系统”分析

2.1题目要求

某航空公司“航空货运管理系统”中的空运费的计算涉及多个因素,通常包括货物重量/体积、运输距离、附加费用、货物类型、客户类型以及市场供需等。题目要求我们计算“计费重量”、“基础运费”等,以及根据航空公司提供的信息,按照一定格式输出。相较于第一次,增加了货物的类型,货物类型的不同,导致费率的计算的不同,由此导致基础运费的不同。同时,此次题目还增加了单一职责原则、里氏代换原则、开闭原则以及合成复用原则、依赖倒转原则的运用。这一变化不仅增加了业务逻辑的复杂性,也对我们的代码设计和实现提出了更高的要求。

2.2类图

共有十一个类:BasicInformation、BasicInformation2、Customer、Sender、Addressee、AbstractGoods、Goods、Flight、Payment、Order、Main;

BasicInformation:用于存储基本的数据,是Customer的父类

Customer:用于存储顾客信息的类

Sender:用于存储发件人信息的类

Addressee:用于存储收件人信息的类

Goods:用于存储货物信息的类

Flight:用于存储航班信息的类

Order:用于存储订单信息的类

Payment:用于判断哪种支付方式的类

Main:主类

2.3SourceMonitor分析结果:

2.4分析

通过 SourceMonitor 工具对代码进行分析,我们获取了一系列关键数据:

复杂度:平均复杂度为 1.05 ,最大复杂度为 2(Order.displayInfo()方法 ),整体代码逻辑复杂程度较低。平均块深度 1.66 ,最大块深度 3 ,说明代码中存在一定的嵌套结构,但不算特别深。

复杂方法:最复杂方法是Order.displayInfo() ,复杂度为 2 ,有 4 条语句,调用深度 2 ,调用次数 4 。相比其他大部分复杂度为 1 的方法,它的逻辑稍复杂些,可能涉及较多的信息展示逻辑或方法调用。

语句情况:有 155 条语句,分支语句占比 2.6% ,方法调用语句 61 条 。分支语句占比低,意味着条件判断逻辑不多;较多的方法调用语句说明代码中方法间的交互较为频繁。

注释情况:带注释的行数占比为 0% ,这是严重不足,会极大影响代码的可读性和可维护性。

2.5心得

有所进步:相对于电梯那次迭代,以及航空货物的第一次迭代,这次有些微的进步。

还需改进:注释太少,可以增加点注释

三、踩坑心得

点击查看代码
import java.util.Scanner;

abstract class BasicInformation{
    private String name;
    private String telephone;
    private String address;

    public BasicInformation(String name,String telephone,String address){
        this.name = name;
        this.telephone = telephone;
        this.address = address;
    }

    abstract public void displayInfo();

    public String getName() {
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone){
        this.telephone = telephone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address){
        this.address = address;
    }
}

class BasicInformation2{
    private String name;
    private String telephone;
    private String address;

    public BasicInformation2(String name,String telephone,String address){
        this.name = name;
        this.telephone = telephone;
        this.address = address;
    }


    public String getName() {
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone){
        this.telephone = telephone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address){
        this.address = address;
    }
}

class Customer extends BasicInformation{
    private String number;

    public Customer(String number, String name, String telephone, String address) {
        super(name, telephone, address);
        this.number = number;
    }

    @Override
    public void displayInfo(){
        System.out.println("客户:" + getName() + "(" + getTelephone() + ")" + "订单信息如下:");
    }
}

class Sender{
    private BasicInformation2 sender;

    public Sender(BasicInformation2 sender){
        this.sender = sender;
    }

    public void displayInfo(){
        System.out.println("发件人姓名:" + sender.getName());
        System.out.println("发件人电话:" + sender.getTelephone());
        System.out.println("发件人地址:" + sender.getAddress());
    }
}

class Addressee{
    private BasicInformation2 addressee;

    public Addressee(BasicInformation2 addressee){
        this.addressee = addressee;
    }

    public void displayInfo(){
        System.out.println("收件人姓名:" + addressee.getName());
        System.out.println("收件人电话:" + addressee.getTelephone());
        System.out.println("收件人地址:" + addressee.getAddress());
    }
}

abstract class AbstractGoods {
    protected String number;
    protected String name;
    protected int width;
    protected int length;
    protected int height;
    protected int weight;

    public AbstractGoods(String number, String name, int width, int length, int height, int weight) {
        this.number = number;
        this.name = name;
        this.width = width;
        this.length = length;
        this.height = height;
        this.weight = weight;
    }

    public abstract double calculateWeight();

    public abstract double calculateRate();

    public abstract double calculateShippingCost();

    public abstract void displayInfo();
}

class Goods extends AbstractGoods {
    public Goods(String number, String name, int width, int length, int height, int weight) {
        super(number, name, width, length, height, weight);
    }

    @Override
    public double calculateWeight() {
        double volumeWeight = (length * width * height) / 6000;
        return volumeWeight > weight? volumeWeight : weight;
    }

    @Override
    public double calculateRate() {
        double billingWeight = calculateWeight();
        if (billingWeight >= 100)
            return 15;
        if (billingWeight >= 50)
            return 25;
        if (billingWeight >= 20)
            return 30;
        return 35;
    }

    @Override
    public double calculateShippingCost() {
        return calculateWeight() * calculateRate();
    }

    @Override
    public void displayInfo() {
        System.out.printf("%s\t%.1f\t%.1f\t%.1f\n", name, calculateWeight(), calculateRate(), calculateShippingCost());
    }
}

class Flight{
    private String flightNum;
    private String flightStart;
    private String flightEnd;
    private String flightDate;
    private double flightMax;

    public Flight(String flightNum,String flightStart,String flightEnd,String flightDate,double flightMax){
        this.flightNum = flightNum;
        this.flightStart = flightStart;
        this.flightEnd = flightEnd;
        this.flightDate = flightDate;
        this.flightMax = flightMax;
    }

    public String getFlightNum() {
        return flightNum;
    }

    public void setFlightNum(String flightNum) {
        this.flightNum = flightNum;
    }

    public String getFlightStart() {
        return flightStart;
    }

    public void setFlightStart(String flightStart) {
        this.flightStart = flightStart;
    }

    public String getFlightEnd() {
        return flightEnd;
    }

    public void setFlightEnd(String flightEnd) {
        this.flightEnd = flightEnd;
    }

    public String getFlightDate() {
        return flightDate;
    }

    public void setFlightDate(String flightDate) {
        this.flightDate = flightDate;
    }

    public double getFlightMax() {
        return flightMax;
    }

    public void setFlightMax(double flightMax) {
        this.flightMax = flightMax;
    }

    public void displayInfo(){
        System.out.println("航班号:" + flightNum);
    }
}

class Order{
    private String orderNum;
    private String orderDate;

    public Order(String orderNum, String orderDate){
        this.orderNum = orderNum;
        this.orderDate = orderDate;
    }

    public void displayInfo(){
        System.out.println("订单号:" + orderNum);
        System.out.println("订单日期:" + orderDate);
    }
}

public class Main{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);

        String customerNum = sc.nextLine();
        String customerName = sc.nextLine();
        String customerTelephone = sc.nextLine();
        String customerAddress = sc.nextLine();
        BasicInformation customer = new Customer(customerNum,customerName,customerTelephone,customerAddress);

        int num = sc.nextInt();
        sc.nextLine();
        Goods[] goods = new Goods[num];
        for(int i = 0; i<num; i++){
            String goodsNum = sc.nextLine();
            String goodsName = sc.nextLine();
            int goodsWidth = sc.nextInt();
            int goodsLength = sc.nextInt();
            int goodsHeight = sc.nextInt();
            int goodsWeight = sc.nextInt();
            sc.nextLine();
            goods[i] = new Goods(goodsNum, goodsName, goodsWidth, goodsLength, goodsHeight, goodsWeight);
        }

        String flightNum = sc.nextLine();
        String flightStart = sc.nextLine();
        String flightEnd = sc.nextLine();
        String flightDate = sc.nextLine();
        double flightMax = sc.nextDouble();
        sc.nextLine();
        Flight flight = new Flight(flightNum,flightStart,flightEnd,flightDate,flightMax);

        String orderNum = sc.nextLine();
        String orderDate = sc.nextLine();
        Order order = new Order(orderNum,orderDate);

        String senderAddress = sc.nextLine();
        String senderName = sc.nextLine();
        String senderTelephone = sc.nextLine();
        BasicInformation2 senderInfo = new BasicInformation2(senderName, senderTelephone, senderAddress);
        Sender sender = new Sender(senderInfo);

        String addresseeAddress = sc.nextLine();
        String addresseeName = sc.nextLine();
        String addresseeTelephone = sc.nextLine();
        BasicInformation2 addresseeInfo = new BasicInformation2(addresseeName, addresseeTelephone, addresseeAddress);
        Addressee addressee = new Addressee(addresseeInfo);

        double totalWeight = 0;
        double totalCost = 0;
        for (Goods good : goods) {
            totalWeight += good.calculateWeight();
            totalCost += good.calculateShippingCost();
        }
        
        if(totalWeight > flightMax){
            System.out.println("The flight with flight number:" + flight.getFlightNum() +" has exceeded its load capacity and cannot carry the order.");
            //System.out.println("its load capacity and cannot carry the order.");
            System.exit(0);
        }
        
        customer.displayInfo();
        System.out.println("-----------------------------------------");
        flight.displayInfo();
        order.displayInfo();
        sender.displayInfo();
        addressee.displayInfo();
        System.out.printf("订单总重量(kg):%.1f\n",totalWeight);
        System.out.printf("微信支付金额:%.1f\n",totalCost);
        System.out.printf("\n");
        System.out.println("货物明细如下:");
        System.out.println("-----------------------------------------");
        System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
        int i = 0;
        for (Goods good : goods) {
            i++;
            System.out.printf("%d\t",i);
            good.displayInfo();
        }

        sc.close();
    }
}
点击查看代码
import java.util.Scanner;

abstract class BasicInformation{
    private String name;
    private String telephone;
    private String address;

    public BasicInformation(String name,String telephone,String address){
        this.name = name;
        this.telephone = telephone;
        this.address = address;
    }

    abstract public void displayInfo();

    public String getName() {
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone){
        this.telephone = telephone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address){
        this.address = address;
    }
}

class BasicInformation2{
    private String name;
    private String telephone;
    private String address;

    public BasicInformation2(String name,String telephone,String address){
        this.name = name;
        this.telephone = telephone;
        this.address = address;
    }


    public String getName() {
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone){
        this.telephone = telephone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address){
        this.address = address;
    }
}

class Customer extends BasicInformation{
    private String number;
    private String type;

    public Customer(String number, String name, String telephone, String address, String type) {
        super(name, telephone, address);
        this.number = number;
        this.type = type;
    }

    @Override
    public void displayInfo(){
        System.out.println("客户:" + getName() + "(" + getTelephone() + ")" + "订单信息如下:");
    }
}

class Sender{
    private BasicInformation2 sender;

    public Sender(BasicInformation2 sender){
        this.sender = sender;
    }

    public void displayInfo(){
        System.out.println("发件人姓名:" + sender.getName());
        System.out.println("发件人电话:" + sender.getTelephone());
        System.out.println("发件人地址:" + sender.getAddress());
    }
}

class Addressee{
    private BasicInformation2 addressee;

    public Addressee(BasicInformation2 addressee){
        this.addressee = addressee;
    }

    public void displayInfo(){
        System.out.println("收件人姓名:" + addressee.getName());
        System.out.println("收件人电话:" + addressee.getTelephone());
        System.out.println("收件人地址:" + addressee.getAddress());
    }
}

abstract class AbstractGoods {
    protected String number;
    protected String name;
    protected int width;
    protected int length;
    protected int height;
    protected int weight;

    public AbstractGoods(String number, String name, int width, int length, int height, int weight) {
        this.number = number;
        this.name = name;
        this.width = width;
        this.length = length;
        this.height = height;
        this.weight = weight;
    }

    public abstract double calculateWeight();

    public abstract double normalRate();

    public abstract double dangerRate();

    public abstract double urgentRate();

    public abstract double calculateShippingCost(String type, String customerType);

    public abstract void displayInfo(String type, String customerType);
}

class Order{
    private String orderNum;
    private String orderDate;
    private String orderType;

    public Order(String orderNum, String orderDate, String orderType){
        this.orderNum = orderNum;
        this.orderDate = orderDate;
        this.orderType = orderType;
    }

    public void displayInfo(){
        System.out.println("订单号:" + orderNum);
        System.out.println("订单日期:" + orderDate);
    }
}

class Goods extends AbstractGoods {
    public Goods(String number, String name, int width, int length, int height, int weight) {
        super(number, name, width, length, height, weight);
    }

    @Override
    public double calculateWeight() {
        double volumeWeight = (length * width * height) / 6000;
        return volumeWeight > weight? volumeWeight : weight;
    }

    @Override
    public double normalRate() {
        double billingWeight = calculateWeight();
        if (billingWeight >= 100)
            return 15;
        if (billingWeight >= 50)
            return 25;
        if (billingWeight >= 20)
            return 30;
        return 35;
    }

    @Override
    public double dangerRate(){
        double billingWeight = calculateWeight();
        if (billingWeight >= 100)
            return 20;
        if (billingWeight >= 50)
            return 30;
        if (billingWeight >= 20)
            return 50;
        return 80;
    }

    @Override
    public double urgentRate(){
        double billingWeight = calculateWeight();
        if (billingWeight >= 100)
            return 30;
        if (billingWeight >= 50)
            return 40;
        if (billingWeight >= 20)
            return 50;
        return 60;
    }

    public double calculateCount(String customerType){
        if(customerType.equals("Individual"))
            return 0.9;
        return 0.8;
    }

    @Override
    public double calculateShippingCost(String type,String customerType) {
        if(type.equals("Normal"))
            return calculateWeight() * normalRate();
        if(type.equals("Expedite"))
            return calculateWeight() * urgentRate();
        return calculateWeight() * dangerRate();
    }

    @Override
    public void displayInfo(String type,String customerType) {
        double count = calculateCount(customerType);
        if(type.equals("Normal"))
            System.out.printf("%s\t%.1f\t%.1f\t%.1f\n", name, calculateWeight(), normalRate(), calculateShippingCost(type,customerType));
        if(type.equals("Expedite"))
            System.out.printf("%s\t%.1f\t%.1f\t%.1f\n", name, calculateWeight(), urgentRate(), calculateShippingCost(type,customerType));
        if(type.equals("Dangerous"))
            System.out.printf("%s\t%.1f\t%.1f\t%.1f\n", name, calculateWeight(), dangerRate(), calculateShippingCost(type,customerType));

    }
}

class Flight{
    private String flightNum;
    private String flightStart;
    private String flightEnd;
    private String flightDate;
    private double flightMax;

    public Flight(String flightNum,String flightStart,String flightEnd,String flightDate,double flightMax){
        this.flightNum = flightNum;
        this.flightStart = flightStart;
        this.flightEnd = flightEnd;
        this.flightDate = flightDate;
        this.flightMax = flightMax;
    }

    public String getFlightNum() {
        return flightNum;
    }

    public void setFlightNum(String flightNum) {
        this.flightNum = flightNum;
    }

    public String getFlightStart() {
        return flightStart;
    }

    public void setFlightStart(String flightStart) {
        this.flightStart = flightStart;
    }

    public String getFlightEnd() {
        return flightEnd;
    }

    public void setFlightEnd(String flightEnd) {
        this.flightEnd = flightEnd;
    }

    public String getFlightDate() {
        return flightDate;
    }

    public void setFlightDate(String flightDate) {
        this.flightDate = flightDate;
    }

    public double getFlightMax() {
        return flightMax;
    }

    public void setFlightMax(double flightMax) {
        this.flightMax = flightMax;
    }

    public void displayInfo(){
        System.out.println("航班号:" + flightNum);
    }
}

class Payment{
    private String payMethod;

    public Payment(String payMethod){
        this.payMethod = payMethod;
    }

    public void displayInfo(){
        if(payMethod.equals("Wechat"))
            System.out.printf("微信");
        else if(payMethod.equals("ALiPay"))
            System.out.printf("支付宝");
        else if(payMethod.equals("Cash"))
            System.out.printf("现金");
    }
}

public class Main{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);

        String customerType = sc.nextLine();
        String customerNum = sc.nextLine();
        String customerName = sc.nextLine();
        String customerTelephone = sc.nextLine();
        String customerAddress = sc.nextLine();
        BasicInformation customer = new Customer(customerNum,customerName,customerTelephone,customerAddress,customerType);

        String goodsType = sc.next();
        int num = sc.nextInt();
        sc.nextLine();
        Goods[] goods = new Goods[num];
        for(int i = 0; i<num; i++){
            String goodsNum = sc.nextLine();
            String goodsName = sc.nextLine();
            int goodsWidth = sc.nextInt();
            int goodsLength = sc.nextInt();
            int goodsHeight = sc.nextInt();
            int goodsWeight = sc.nextInt();
            sc.nextLine();
            goods[i] = new Goods(goodsNum, goodsName, goodsWidth, goodsLength, goodsHeight, goodsWeight);
        }

        String flightNum = sc.nextLine();
        String flightStart = sc.nextLine();
        String flightEnd = sc.nextLine();
        String flightDate = sc.nextLine();
        double flightMax = sc.nextDouble();
        sc.nextLine();
        Flight flight = new Flight(flightNum,flightStart,flightEnd,flightDate,flightMax);

        String orderNum = sc.nextLine();
        String orderDate = sc.nextLine();
        Order order = new Order(orderNum,orderDate,goodsType);

        String senderAddress = sc.nextLine();
        String senderName = sc.nextLine();
        String senderTelephone = sc.nextLine();
        BasicInformation2 senderInfo = new BasicInformation2(senderName, senderTelephone, senderAddress);
        Sender sender = new Sender(senderInfo);

        String addresseeAddress = sc.nextLine();
        String addresseeName = sc.nextLine();
        String addresseeTelephone = sc.nextLine();
        BasicInformation2 addresseeInfo = new BasicInformation2(addresseeName, addresseeTelephone, addresseeAddress);
        Addressee addressee = new Addressee(addresseeInfo);

        String paymethod = sc.next();
        Payment payment = new Payment(paymethod);
        double totalWeight = 0;
        double totalCost = 0;
        for (Goods good : goods) {
            totalWeight += good.calculateWeight();
            totalCost += good.calculateShippingCost(goodsType,customerType)*good.calculateCount(customerType);
        }

        if(totalWeight > flightMax){
            System.out.println("The flight with flight number:" + flight.getFlightNum() +" has exceeded its load capacity and cannot carry the order.");
            System.exit(0);
        }

        customer.displayInfo();
        System.out.println("-----------------------------------------");
        flight.displayInfo();
        order.displayInfo();
        sender.displayInfo();
        addressee.displayInfo();
        System.out.printf("订单总重量(kg):%.1f\n",totalWeight);
        payment.displayInfo();
        System.out.printf("支付金额:%.1f\n",totalCost);
        System.out.printf("\n");
        System.out.println("货物明细如下:");
        System.out.println("-----------------------------------------");
        System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
        int i = 0;
        for (Goods good : goods) {
            i++;
            System.out.printf("%d\t",i);
            good.displayInfo(goodsType,customerType);
        }

        sc.close();
    }
}

1.异常测试有误

第一次提交的时候,其他三个测试都过了,只有最后一个异常测试的没有过,通过我仔细的阅读,发现我漏了一种情况,然后我就加上去了。加上去之后又发现我还是错了,于是我就更仔细阅读,但是尝试在多次之后,并未取得正确答案,于是我便求救同学,在同学的帮助下,我发现我少了一个空格。这件事告诉我一定要认真!

2.忽略了抽象类不能实例化

在我第一次写航空货物这道题的时候,将BasicInformation设置成抽象类,但在主类中,我又将它实例化了,犯了一个大错误。于是我弄一个和它一样的类出来,就是名字不一样,不过这样虽然能成功,但是重复了其实不太好。这个问题告诉我还是不能忽略这些细枝末节的事情!
(无图片)

3.货物类型弄错

在第二次写这个题目的时候,也就是迭代的时候,加了货物的类型,不同类型的货物所对应的费率不同。本来这个很简单,只需要加方法,但是由于我弄错了危险货物和加急货物,导致基础运费计算错误,浪费了我好多时间。这道题告诉我一定要好好学英语!

4.将折扣乘错了地方

迭代的时候,增加了打折这个功能。但是我误以为折扣是乘在最终的总费用上,导致我花了好多时间来找错误。这让我明白了要好好看题目!同时,在实现新功能时,要养成先进行逻辑分析和设计的习惯,绘制流程图或伪代码,明确各个步骤的顺序和逻辑关系,避免因理解偏差而导致错误,提高代码的准确性和可靠性。

四、改进建议

1.设计优化

1.1避免类重复

在我这两次的作业中,有两个类实际重复了,它们内部完全相等,只不过一个是抽象类,一个不是抽象类而已。

1.2统一抽象类设计

客户 (Customer) 类继承自 BasicInformation,但发货人和收货人使用 BasicInformation2,应统一设计

1.3简化计费逻辑

Goods 类中的 calculateShippingCost 和 displayInfo 方法包含重复的条件判断,可重构为策略模式

(以下为优化的代码)

点击查看代码
// 合并 BasicInformation 和 BasicInformation2
class ContactInfo {
    private String name;
    private String telephone;
    private String address;

    public ContactInfo(String name, String telephone, String address) {
        this.name = name;
        this.telephone = telephone;
        this.address = address;
    }
    
    // Getters and setters
    // displayInfo 方法可在这里实现,或在使用处实现
}

// 发货人和收货人可统一使用 ContactInfo
class Sender {
    private ContactInfo contact;

    public Sender(ContactInfo contact) {
        this.contact = contact;
    }
    
    // 其他方法
}

// 优化 Goods 类的计费逻辑
enum GoodsType {
    NORMAL, EXPEDITE, DANGEROUS
}

class Goods extends AbstractGoods {
    // 其他代码保持不变
    
    @Override
    public double calculateShippingCost(String type, String customerType) {
        GoodsType goodsType = GoodsType.valueOf(type.toUpperCase());
        double rate = switch(goodsType) {
            case NORMAL -> normalRate();
            case EXPEDITE -> urgentRate();
            case DANGEROUS -> dangerRate();
        };
        
        return calculateWeight() * rate * calculateCount(customerType);
    }
    
    @Override
    public void displayInfo(String type, String customerType) {
        GoodsType goodsType = GoodsType.valueOf(type.toUpperCase());
        double rate = switch(goodsType) {
            case NORMAL -> normalRate();
            case EXPEDITE -> urgentRate();
            case DANGEROUS -> dangerRate();
        };
        
        double cost = calculateWeight() * rate * calculateCount(customerType);
        System.out.printf("%s\t%.1f\t%.1f\t%.1f\n", name, calculateWeight(), rate, cost);
    }
}

2.代码质量提升

2.1优化异常处理

使用 try-with-resources 管理 Scanner 资源,添加更具体的异常处理逻辑

2.2提高代码可读性

添加必要的注释解释复杂逻辑,使用更具描述性的变量名,提取重复代码为独立方法

五、总结

1.内容概述

本篇Blog包含以下内容:前言、代码的设计以及对代码的分析、运用SourceMonitor进行分析、踩坑心得以及对代码的改进。

2.学习收获与未来展望

通过两次的迭代,我学习到了很多。学会了如何应用这些原则,如单一职责原则,里氏代换原则,开闭原则等。我认识到了学会这些原则以及运用好这些原则是件多么重要的事,它对我们代码的可维护性非常重要!

3.实践中的教训与反思

异常测试中因漏写空格导致错误、折扣计算位置偏差等问题,提醒我需更细致地审题和调试,避免 “小错误” 引发大问题。货物类型(如 “Expedite”“Dangerous”)的混淆,凸显了技术英语在编程中的基础作用,需加强专业词汇积累。

4.建议

希望输出题目指定语句的时候,格式要说清楚,不要出现题目要求和测试点有细微差错的情况。

posted @ 2025-05-25 16:47  D_0723  阅读(29)  评论(0)    收藏  举报