第二次blog作业

一,前言:
又经历了两周的面向对象课程的学习,又迎来了第二次pta作业总结biog。相较于上一次代码迭代程序中的一地鸡毛,此次的航空运输代码迭代程序题,我算是有了不小的进展。当然,进步是有的,但是这不是尽头,通过这次blog作业的总结,我更要从中看到仍存在的问题,进行新一轮的努力与进步。本次的航空客运代迭代题目,难度相较于之前有所降低,但是要求了更加流畅的类设计和对继承多态技术更好的应用,以此来完善带代码,保证代码的可维护性和可扩展性。
二,题目分析:
1,第八次作业中的航空客运题:
题目要求:
某航空公司“航空货运管理系统”中的空运费的计算涉及多个因素,通常包
括货物重量/体积、运输距离、附加费用、货物类型、客户类型以及市场供需等。
本次作业主要考虑货物重量/体积,以下是具体的计算方式和关键要点:
一、计费重量的确定
空运以实际重量(Gross Weight)和体积重量(Volume Weight)中的较
高者作为计费重量。
计算公式:
体积重量(kg) = 货物体积(长×宽×高,单位:厘米)÷ 6000
示例:
若货物实际重量为 80kg,体积为 120cm×80cm×60cm,则:
体积重量 = (120×80×60) ÷ 6000 = 96kg
计费重量取 96kg(因 96kg > 80kg)。
二、基础运费计算
费率(Rate):航空公司或货代根据航线、货物类型、市场行情等制定(如
CNY 30/kg)。本次作业费率采用分段计算方式。
公式:基础运费 = 计费重量 × 费率
三、题目说明
本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场所在城市,航班降落机场所在城市,航班
日期,航班最大载重量)
客户填写货运订单并进行支付,需要提供如下信息:
 客户信息(姓名,电话号码等)
 货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
 运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选
航班号,订单日期)
 支付方式(支付宝支付、微信支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独
计费。
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信
息报表及货物明细报表。
四、题目要求
本次题目重点考核面向对象设计原则中的单一职责原则、里氏代换原则、开
闭原则以及合成复用原则。
输入的格式严格遵照:
客户编号
客户姓名
客户电话
客户地址
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
根据上述要求我做出了类图为下的设计:
对此我完善了我的代码:`import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Flight {
private String flightNumber;
private String departureCity;
private String arrivalCity;
private String flightDate;
private double maxLoadWeight;

public Flight(String flightNumber, String departureCity, String arrivalCity, String flightDate, double maxLoadWeight) {
    this.flightNumber = flightNumber;
    this.departureCity = departureCity;
    this.arrivalCity = arrivalCity;
    this.flightDate = flightDate;
    this.maxLoadWeight = maxLoadWeight;
}

public String getFlightNumber() {
    return flightNumber;
}

public String getDepartureCity() {
    return departureCity;
}

public String getArrivalCity() {
    return arrivalCity;
}

public String getFlightDate() {
    return flightDate;
}

public double getMaxLoadWeight() {
    return maxLoadWeight;
}

}

class Customer {
private int bianhao;
private String name;
private String phoneNumber;
private String address;

public Customer(int bianhao, String name, String phoneNumber, String address) {
    this.bianhao = bianhao;
    this.name = name;
    this.phoneNumber = phoneNumber;
    this.address = address;
}

public int getbianhao() {
    return bianhao;
}

public String getName() {
    return name;
}

public String getPhoneNumber() {
    return phoneNumber;
}

public String getAddress() {
    return address;
}

}

class Person {
private String name;
private String phone;
private String address;

public Person(String name, String phone, String address) {
    this.name = name;
    this.phone = phone;
    this.address = address;
}

public String getName() {
    return name;
}

public String getPhone() {
    return phone;
}

public String getAddress() {
    return address;
}

}

class Sender extends Person {
public Sender(String name, String phone, String address) {
super(name, phone, address);
}
}

class Receiver extends Person {
public Receiver(String name, String phone, String address) {
super(name, phone, address);
}
}

class Cargo {
private String name;
private int length;
private int width;
private int height;
private int actualWeight;
private String serialNumber;

public Cargo(String name, int length, int width, int height, int actualWeight, String serialNumber) {
    this.name = name;
    this.length = length;
    this.width = width;
    this.height = height;
    this.actualWeight = actualWeight;
    this.serialNumber = serialNumber;
}

public String getName() {
    return name;
}

public int getLength() {
    return length;
}

public int getWidth() {
    return width;
}

public int getHeight() {
    return height;
}

public int getActualWeight() {
    return actualWeight;
}

public String getSerialNumber() {
    return serialNumber;
}

public int calculateVolumeWeight() {
    return (length * width * height) / 6000;
}

public int calculateChargeableWeight() {
    return Math.max(actualWeight, calculateVolumeWeight());
}

public double calculateBasicFreight() {
    int chargeableWeight = calculateChargeableWeight();
    if (chargeableWeight < 20) {
        return chargeableWeight * 35;
    } else if (chargeableWeight < 50) {
        return chargeableWeight * 30;
    } else if (chargeableWeight < 100) {
        return chargeableWeight * 25;
    } else {
        return chargeableWeight * 15;
    }
}

}

class CargoOrder {
private String orderDate;
private List cargoList;
private String orderNumber;

public CargoOrder(String orderDate, String orderNumber) {
    this.orderDate = orderDate;
    this.cargoList = new ArrayList<>();
    this.orderNumber = orderNumber;
}

public CargoOrder() {
    this.cargoList = new ArrayList<>();
}

public void addCargo(Cargo cargo) {
    cargoList.add(cargo);
}

public String getOrderDate() {
    return orderDate;
}

public void setOrderDate(String orderDate) {
    this.orderDate = orderDate;
}

public List<Cargo> getCargoList() {
    return cargoList;
}

public String getOrderNumber() {
    return orderNumber;
}

public void setOrderNumber(String orderNumber) {
    this.orderNumber = orderNumber;
}

public double calculateTotalWeight() {
    double total = 0;
    for (Cargo cargo : cargoList) {
        total += cargo.calculateChargeableWeight();
    }
    return total;
}

public double calculateTotalFreight() {
    double total = 0;
    for (Cargo cargo : cargoList) {
        total += cargo.calculateBasicFreight();
    }
    return total;
}

}

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int j=1;
CargoOrder cargoOrder = new CargoOrder();
int customerBianhao = scanner.nextInt();
scanner.nextLine();
String customerName = scanner.nextLine();
String customerPhone = scanner.nextLine();
String customerAddress = scanner.nextLine();
Customer customer = new Customer(customerBianhao, customerName, customerPhone, customerAddress);
int cargoNumber = scanner.nextInt();
scanner.nextLine();
for (int i = 0; i < cargoNumber; i++) {
String serialNumber = scanner.nextLine();
String cargoName = scanner.nextLine();
int width = scanner.nextInt();
int length = scanner.nextInt();
int height = scanner.nextInt();
int actualWeight = scanner.nextInt();
scanner.nextLine();
Cargo cargo = new Cargo(cargoName, length, width, height, actualWeight, serialNumber);
cargoOrder.addCargo(cargo);
}

    String flightNumber = scanner.nextLine();
    String departureCity = scanner.nextLine();
    String arrivalCity = scanner.nextLine();
    String flightDate = scanner.nextLine();
    double maxLoadWeight = scanner.nextDouble();
    Flight flight = new Flight(flightNumber, departureCity, arrivalCity, flightDate, maxLoadWeight);
    scanner.nextLine();
    String orderNumber = scanner.nextLine();
    String orderDate = scanner.nextLine();
    cargoOrder.setOrderDate(orderDate);
    cargoOrder.setOrderNumber(orderNumber);
    String senderAddress = scanner.nextLine();
    String senderName = scanner.nextLine();
    String senderPhone = scanner.nextLine();
    Sender sender = new Sender(senderName, senderPhone, senderAddress);
    String receiverAddress = scanner.nextLine();
    String receiverName = scanner.nextLine();
    String receiverPhone = scanner.nextLine();
    Receiver receiver = new Receiver(receiverName, receiverPhone, receiverAddress);

    double totalWeight = cargoOrder.calculateTotalWeight();
      
    if (totalWeight > flight.getMaxLoadWeight()) {
        System.out.println("The flight with flight number:" + flight.getFlightNumber() + " has exceeded its load capacity and cannot carry the order.");
        System.exit(0);
    }
    System.out.println("客户:" + customer.getName() + "(" + customer.getPhoneNumber() + ")订单信息如下:");
    System.out.println("-----------------------------------------");
    System.out.println("航班号:" + flight.getFlightNumber());
    System.out.println("订单号:" + cargoOrder.getOrderNumber());
    System.out.println("订单日期:" + cargoOrder.getOrderDate());
    System.out.println("发件人姓名:" + sender.getName());
    System.out.println("发件人电话:" + sender.getPhone());
    System.out.println("发件人地址:" + sender.getAddress());
    System.out.println("收件人姓名:" + receiver.getName());
    System.out.println("收件人电话:" + receiver.getPhone());
    System.out.println("收件人地址:" + receiver.getAddress());
    System.out.println("订单总重量(kg):" + totalWeight);
    System.out.println("微信支付金额:" + cargoOrder.calculateTotalFreight());
    System.out.println("\n货物明细如下:");
    System.out.println("-----------------------------------------");
    System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
    for (Cargo cargo : cargoOrder.getCargoList()) {
        System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n", j, cargo.getName(), cargo.calculateChargeableWeight()/1.0, (cargo.calculateChargeableWeight() < 20? 35 : cargo.calculateChargeableWeight() < 50? 30 : cargo.calculateChargeableWeight() < 100? 25 : 15)/1.0, cargo.calculateBasicFreight());
    j++;
    }
    scanner.close();
}

}`
代码中基本遵顼面向对象基本原则:单一职责原则(客户、货物、航班、订单类各自独立,各自有各自的功能);里氏替换原则(子类可以正确继承父类);开闭原则(做到对扩展开发,对修改关闭);合成复用原则(对象间通过组合协作)。
本次作业的考点在于流畅的类设计,要运作好各个类之间的关联,不会过度耦合,并熟练遵循里氏替换原则。


根据代码分析有以下问题:
平均每个类的方法数(Methods/Class:4.75):意味着每个类承担的功能相对较多,可能存在类的职责不够单一的情况,后续可考虑进一步拆分以符合单一职责原则。
最大复杂度(Max Complexity:5):最大复杂度为 5,表明代码中存在部分方法逻辑较为复杂,可能难以理解和维护,需要检查这些高复杂度方法,考虑重构简化。
平均复杂度(Avg Complexity:1.24):平均复杂度较低,说明大部分方法相对简单,但结合最大复杂度,仍需关注复杂方法。
注释占比(% Comments:0.0%):没有注释是严重问题,后期他人阅读和理解代码功能、逻辑意图会非常困难,添加注释迫在眉睫,包括类、方法功能说明,关键代码段解释等。
2.第九题目集航空客运问题:
在第八次左右基础上,添加了顾客类型,货物类型等新属性,从而实现了不类型的费率,折扣率不同,在整体结果没有大改动的情况下,我选择引入了switch-case,以此来解决不类型对应不同费率和折扣的情况。
类图如下:
根据设计完善了代码:`import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Flight {
private String flightNumber;
private String departureCity;
private String arrivalCity;
private String flightDate;
private double maxLoadWeight;

public Flight(String flightNumber, String departureCity, String arrivalCity, String flightDate, double maxLoadWeight) {
    this.flightNumber = flightNumber;
    this.departureCity = departureCity;
    this.arrivalCity = arrivalCity;
    this.flightDate = flightDate;
    this.maxLoadWeight = maxLoadWeight;
}

public String getFlightNumber() {
    return flightNumber;
}

public String getDepartureCity() {
    return departureCity;
}

public String getArrivalCity() {
    return arrivalCity;
}

public String getFlightDate() {
    return flightDate;
}

public double getMaxLoadWeight() {
    return maxLoadWeight;
}

}

class Customer {
private String type;
private int bianhao;
private String name;
private String phoneNumber;
private String address;
private String pay;

public Customer(String type, int bianhao, String name, String phoneNumber, String address) {
    this.type = type;
    this.bianhao = bianhao;
    this.name = name;
    this.phoneNumber = phoneNumber;
    this.address = address;
}

public String getType() {
    return type;
}

public int getBianhao() {
    return bianhao;
}

public String getName() {
    return name;
}

public String getPhoneNumber() {
    return phoneNumber;
}

public String getAddress() {
    return address;
}

public String getPay() {
    return pay;
}

public void setPay(String pay) {
    this.pay = pay;
}

}

class Person {
private String name;
private String phone;
private String address;

public Person(String name, String phone, String address) {
    this.name = name;
    this.phone = phone;
    this.address = address;
}

public String getName() {
    return name;
}

public String getPhone() {
    return phone;
}

public String getAddress() {
    return address;
}

}

class Sender extends Person {
public Sender(String name, String phone, String address) {
super(name, phone, address);
}
}

class Receiver extends Person {
public Receiver(String name, String phone, String address) {
super(name, phone, address);
}
}

class Cargo {
private String name;
private int length;
private int width;
private int height;
private int actualWeight;
private String serialNumber;
private CargoOrder cargoOrder;

public Cargo(String name, int length, int width, int height, int actualWeight, String serialNumber, CargoOrder cargoOrder) {
    this.name = name;
    this.length = length;
    this.width = width;
    this.height = height;
    this.actualWeight = actualWeight;
    this.serialNumber = serialNumber;
    this.cargoOrder = cargoOrder;
}

public String getName() {
    return name;
}

public int getLength() {
    return length;
}

public int getWidth() {
    return width;
}

public int getHeight() {
    return height;
}

public int getActualWeight() {
    return actualWeight;
}

public String getSerialNumber() {
    return serialNumber;
}

public int calculateVolumeWeight() {
    return (length * width * height) / 6000;
}

public int calculateChargeableWeight() {
    return Math.max(actualWeight, calculateVolumeWeight());
}

public double calculateBasicFreight() {
    int chargeableWeight = calculateChargeableWeight();
    switch (cargoOrder.getCargoType()) {
        case "Normal":
            if (chargeableWeight < 20) {
                return chargeableWeight * 35;
            } else if (chargeableWeight < 50) {
                return chargeableWeight * 30;
            } else if (chargeableWeight < 100) {
                return chargeableWeight * 25;
            } else {
                return chargeableWeight * 15;
            }
        case "Dangerous":
            if (chargeableWeight < 20) {
                return chargeableWeight * 80;
            } else if (chargeableWeight < 50) {
                return chargeableWeight * 50;
            } else if (chargeableWeight < 100) {
                return chargeableWeight * 30;
            } else {
                return chargeableWeight * 20;
            }
        case "Expedite":
            if (chargeableWeight < 20) {
                return chargeableWeight * 60;
            } else if (chargeableWeight < 50) {
                return chargeableWeight * 50;
            } else if (chargeableWeight < 100) {
                return chargeableWeight * 40;
            } else {
                return chargeableWeight * 30;
            }
        default:
            return 0;
    }
}

}

class CargoOrder {
private String cargoType;
private String orderDate;
private List cargoList;
private String orderNumber;
private Customer customer;

public CargoOrder(String cargoType, String orderDate, String orderNumber, Customer customer) {
    this.cargoType = cargoType;
    this.orderDate = orderDate;
    this.cargoList = new ArrayList<>();
    this.orderNumber = orderNumber;
    this.customer = customer;
}

public CargoOrder() {
    this.cargoList = new ArrayList<>();
}

public void addCargo(Cargo cargo) {
    cargoList.add(cargo);
}

public String getOrderDate() {
    return orderDate;
}

public void setOrderDate(String orderDate) {
    this.orderDate = orderDate;
}

public List<Cargo> getCargoList() {
    return cargoList;
}

public String getOrderNumber() {
    return orderNumber;
}

public void setCargoType(String cargoType) {
    this.cargoType = cargoType;
}

public String getCargoType() {
    return cargoType;
}

public void setOrderNumber(String orderNumber) {
    this.orderNumber = orderNumber;
}

public double calculateTotalWeight() {
    double total = 0;
    for (Cargo cargo : cargoList) {
        total += cargo.calculateChargeableWeight();
    }
    return total;
}

public double calculateTotalFreight() {
    double total = 0;
    for (Cargo cargo : cargoList) {
        total += cargo.calculateBasicFreight();
    }
    if (customer.getType().equals("Individual")) {
        total *= 0.9; //
    } else if (customer.getType().equals("Corporate")) {
        total *= 0.8; //
    }
    return total;
}

}

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

    String customerType = scanner.nextLine();
    int customerBianhao = scanner.nextInt();
    scanner.nextLine();
    String customerName = scanner.nextLine();
    String customerPhone = scanner.nextLine();
    String customerAddress = scanner.nextLine();
    Customer customer = new Customer(customerType, customerBianhao, customerName, customerPhone, customerAddress);

    String cargoType = scanner.nextLine();
    int cargoNumber = scanner.nextInt();
    scanner.nextLine();
    CargoOrder cargoOrder = new CargoOrder(cargoType, "", "", customer);

    for (int i = 0; i < cargoNumber; i++) {
        String serialNumber = scanner.nextLine();
        String cargoName = scanner.nextLine();
        int width = scanner.nextInt();
        int length = scanner.nextInt();
        int height = scanner.nextInt();
        int actualWeight = scanner.nextInt();
        scanner.nextLine();
        Cargo cargo = new Cargo(cargoName, length, width, height, actualWeight, serialNumber, cargoOrder);
        cargoOrder.addCargo(cargo);
    }

    String flightNumber = scanner.nextLine();
    String departureCity = scanner.nextLine();
    String arrivalCity = scanner.nextLine();
    String flightDate = scanner.nextLine();
    double maxLoadWeight = scanner.nextDouble();
    scanner.nextLine();
    Flight flight = new Flight(flightNumber, departureCity, arrivalCity, flightDate, maxLoadWeight);

    String orderNumber = scanner.nextLine();
    String orderDate = scanner.nextLine();
    cargoOrder.setOrderDate(orderDate);
    cargoOrder.setOrderNumber(orderNumber);

    String senderAddress = scanner.nextLine();
    String senderName = scanner.nextLine();
    String senderPhone = scanner.nextLine();
    Sender sender = new Sender(senderName, senderPhone, senderAddress);

    String receiverAddress = scanner.nextLine();
    String receiverName = scanner.nextLine();
    String receiverPhone = scanner.nextLine();
    Receiver receiver = new Receiver(receiverName, receiverPhone, receiverAddress);

    String pay = scanner.nextLine();
    switch (pay) {
        case "Wechat":
            customer.setPay("微信");
            break;
        case "ALiPay":
            customer.setPay("支付宝");
            break;
        case "Cash":
            customer.setPay("现金");
            break;
    }

    double totalWeight = cargoOrder.calculateTotalWeight();

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

    System.out.println("客户:" + customer.getName() + "(" + customer.getPhoneNumber() + ")订单信息如下:");
    System.out.println("-----------------------------------------");
    System.out.println("航班号:" + flight.getFlightNumber());
    System.out.println("订单号:" + cargoOrder.getOrderNumber());
    System.out.println("订单日期:" + cargoOrder.getOrderDate());
    System.out.println("发件人姓名:" + sender.getName());
    System.out.println("发件人电话:" + sender.getPhone());
    System.out.println("发件人地址:" + sender.getAddress());
    System.out.println("收件人姓名:" + receiver.getName());
    System.out.println("收件人电话:" + receiver.getPhone());
    System.out.println("收件人地址:" + receiver.getAddress());
    System.out.println("订单总重量(kg):" + totalWeight);
    System.out.println(customer.getPay() + "支付金额:" + cargoOrder.calculateTotalFreight());

    System.out.println("\n货物明细如下:");
    System.out.println("-----------------------------------------");
    System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
    for (Cargo cargo : cargoOrder.getCargoList()) {
        int chargeableWeight = cargo.calculateChargeableWeight();
        double rate = 0;
        switch (cargoOrder.getCargoType()) {
            case "Normal":
                rate = chargeableWeight < 20 ? 35 : chargeableWeight < 50 ? 30 : chargeableWeight < 100 ? 25 : 15;
                break;
            case "Dangerous":
                rate = chargeableWeight < 20 ? 80 : chargeableWeight < 50 ? 50 : chargeableWeight < 100 ? 30 : 20;
                break;
            case "Expedite":
                rate = chargeableWeight < 20 ? 60 : chargeableWeight < 50 ? 50 : chargeableWeight < 100 ? 40 : 30;
                break;
        }
        System.out.printf("%d\t%s\t%.1f\t%.1f\t%.1f\n", 
            j, 
            cargo.getName(), 
            (double)chargeableWeight, 
            rate, 
            cargo.calculateBasicFreight());
        j++;
    }
    scanner.close();
}

}`
整体构造不变,完成了新属性和switch-case的引入,执行便水到渠成。

问题:最大复杂度(Max Complexity:14):最大复杂度数值高达 14,表明代码中存在部分方法逻辑极为复杂,可能包含大量嵌套的条件判断、循环等结构,可读性和可维护性差,是重点的重构对象。
平均复杂度(Avg Complexity:1.40):平均复杂度相对较低,说明大部分方法相对简单,但由于存在高复杂度的方法,仍需对整体代码复杂度进行优化。
在加入了switch-case的情况下,某一方法的复杂度直线飙升,之后需要改进。
本次的代码里有了最基本的注释,但是仍需要加强,以便于阅读。
三,反思与总结:此次作业表面上是拿到了分数,但是代码写的非常不好,面向对象原则实现的不够突出,方法的最大复杂度也高,需要重点重构。同时,注释也是个大问题,好的代码师需要更多的代码以便于其他人更直观的了解其代码。最主要的一点,这次的作业代码中我没有加入控制类以完善单一职责原则与迪米特法则,在接下来的代码训练中,我会学着去完善。

posted @ 2025-05-25 21:15  月七不是七月  阅读(24)  评论(0)    收藏  举报