luo-9

 

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

题目
某航空公司“航空货运管理系统”中的空运费的计算涉及多个因素,通常包括货物重量/体积、运输距离、附加费用、货物类型、客户类型以及市场供需等。
本次作业主要考虑货物重量/体积,以下是具体的计算方式和关键要点:
一、计费重量的确定
空运以实际重量(GrossWeight)和体积重量(VolumeWeight)中的较高者作为计费重量。
计算公式:
体积重量(kg)= 货物体积(长×宽×高,单位:厘米)÷6000
示例:
若货物实际重量为80kg,体积为120cm×80cm×60cm,则:
体积重量 =(120×80×60)÷6000=96kg
计费重量取96kg(因96kg>80kg)。
二、基础运费计算
费率(Rate):航空公司或货代根据航线、货物类型、市场行情等制定(如
CNY 30/kg)。本次作业费率采用分段计算方式:

公式:基础运费 = 计费重量 × 费率
三、题目说明
本次题目模拟某客户到该航空公司办理一次货运业务的过程:
航空公司提供如下信息:
航班信息(航班号,航班起飞机场所在城市,航班降落机场所在城市,航班日期,航班最大载重量)
客户填写货运订单并进行支付,需要提供如下信息:
 客户信息(姓名,电话号码等)
 货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
 运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选航班号,订单日期)
 支付方式(支付宝支付、微信支付)
注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独计费。
程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信息报表及货物明细报表。
四、题目要求
本次题目重点考核面向对象设计原则中的单一职责原则、里氏代换原则、开闭原则以及合成复用原则
设计因素:单一职责原则(40%)、里氏代换原则(20%)、开闭原则(20%)、
合成复用原则(20%)
输入格式:
按如下顺序分别输入客户信息、货物信息、航班信息以及订单信息。
客户编号
客户姓名
客户电话
客户地址
运送货物数量
[货物编号
货物名称
货物宽度
货物长度
货物高度
货物重量
]//[]内的内容输入次数取决于“运送货物数量”,输入不包含“[]”
航班号
航班起飞机场
航班降落机场
航班日期(格式为YYYY-MM-DD)
航班最大载重量
订单编号
订单日期(格式为YYYY-MM-DD)
发件人地址
发件人姓名
发件人电话
收件人地址
收件人姓名
收件人电话
输出格式:
如果订单中货物重量超过航班剩余载重量,程序输出The flight with flight number:航班号 has exceeded its load capacity and cannot carry the order. ,程序终止运行。
如果航班载重量可以承接该订单,输出如下:

点击查看代码
客户:姓名(电话)订单信息如下:
-----------------------------------------
航班号:
订单号:
订单日期:
发件人姓名:
发件人电话:
发件人地址:
收件人姓名:
收件人电话:
收件人地址:
订单总重量(kg):
微信支付金额:

货物明细如下:
-----------------------------------------
明细编号    货物名称    计费重量    计费费率    应交运费
1    ...
2    ...
输入样例:
点击查看代码
10001
郭靖
13807911234
南昌航空大学
2
101
发电机
80
60
40
80
102
信号发生器
55
70
60
45
MU1234
昌北国际机场
大兴国际机场
2025-04-22
1000
900001
2025-04-22
南昌大学
洪七公
18907912325
北京大学
黄药师
13607912546
输出样例:
点击查看代码
客户:郭靖(13807911234)订单信息如下:
-----------------------------------------
航班号:MU1234
订单号:900001
订单日期:2025-04-22
发件人姓名:洪七公
发件人电话:18907912325
发件人地址:南昌大学
收件人姓名:黄药师
收件人电话:13607912546
收件人地址:北京大学
订单总重量(kg):125.0
微信支付金额:3350.0

货物明细如下:
-----------------------------------------
明细编号    货物名称    计费重量    计费费率    应交运费
1    发电机    80.0    25.0    2000.0
2    信号发生器    45.0    30.0    1350.0

我的源码

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

class Cargo {
    private int id;
    private String name;
    private double width;
    private double length;
    private double height;
    private double weight;

    public Cargo(int id, String name, double width, double length, double height, double weight) {
        this.id = id;
        this.name = name;
        this.width = width;
        this.length = length;
        this.height = height;
        this.weight = weight;
    }

    // 计算体积重量
    public double calculateVolumeWeight() {
        return (width * length * height) / 6000;
    }

    // 获取计费重量
    public double getChargeableWeight() {
        double volumeWeight = calculateVolumeWeight();
        return Math.max(weight, volumeWeight);
    }

    // 获取计费费率
    public double getRate() {
        double chargeableWeight = getChargeableWeight();
        if (chargeableWeight < 20) {
            return 35;
        } else if (chargeableWeight < 50) {
            return 30;
        } else if (chargeableWeight < 100) {
            return 25;
        } else {
            return 15;
        }
    }

    // 计算应交运费
    public double calculateFreight() {
        return getChargeableWeight() * getRate();
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public double getChargeableWeightFormatted() {
        return Math.round(getChargeableWeight() * 10) / 10.0;
    }

    public double getRateFormatted() {
        return Math.round(getRate() * 10) / 10.0;
    }

    public double getCalculateFreightFormatted() {
        return Math.round(calculateFreight() * 10) / 10.0;
    }
}

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

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

    public String getFlightNumber() {
        return flightNumber;
    }

    public double getMaxLoad() {
        return maxLoad;
    }
}

class Order {
    private int orderId;
    private String orderDate;
    private String senderAddress;
    private String senderName;
    private String senderPhone;
    private String recipientAddress;
    private String recipientName;
    private String recipientPhone;
    private List<Cargo> cargoList;
    private double totalWeight;

    public Order(int orderId, String orderDate, String senderAddress, String senderName, String senderPhone,
                 String recipientAddress, String recipientName, String recipientPhone) {
        this.orderId = orderId;
        this.orderDate = orderDate;
        this.senderAddress = senderAddress;
        this.senderName = senderName;
        this.senderPhone = senderPhone;
        this.recipientAddress = recipientAddress;
        this.recipientName = recipientName;
        this.recipientPhone = recipientPhone;
        this.cargoList = new ArrayList<>();
        this.totalWeight = 0;
    }

    public void addCargo(Cargo cargo) {
        cargoList.add(cargo);
        totalWeight += cargo.getChargeableWeight();
    }

    public int getOrderId() {
        return orderId;
    }

    public String getOrderDate() {
        return orderDate;
    }

    public String getSenderAddress() {
        return senderAddress;
    }

    public String getSenderName() {
        return senderName;
    }

    public String getSenderPhone() {
        return senderPhone;
    }

    public String getRecipientAddress() {
        return recipientAddress;
    }

    public String getRecipientName() {
        return recipientName;
    }

    public String getRecipientPhone() {
        return recipientPhone;
    }

    public double getTotalWeightFormatted() {
        return Math.round(totalWeight * 10) / 10.0;
    }

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

    public double getTotalFreightFormatted() {
        return Math.round(calculateTotalFreight() * 10) / 10.0;
    }
}

class Customer {
    private int id;
    private String name;
    private String phone;
    private String address;

    public Customer(int id, String name, String phone, String address) {
        this.id = id;
        this.name = name;
        this.phone = phone;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public String getPhone() {
        return phone;
    }
}

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

        // 输入客户信息
        int customerId = scanner.nextInt();
        String customerName = scanner.next();
        String customerPhone = scanner.next();
        String customerAddress = scanner.next();
        Customer customer = new Customer(customerId, customerName, customerPhone, customerAddress);

        // 输入货物信息
        int cargoNum = scanner.nextInt();
        List<Cargo> cargoList = new ArrayList<>();
        for (int i = 0; i < cargoNum; i++) {
            int cargoId = scanner.nextInt();
            String cargoName = scanner.next();
            double width = scanner.nextDouble();
            double length = scanner.nextDouble();
            double height = scanner.nextDouble();
            double weight = scanner.nextDouble();
            Cargo cargo = new Cargo(cargoId, cargoName, width, length, height, weight);
            cargoList.add(cargo);
        }

        // 输入航班信息
        String flightNumber = scanner.next();
        String departureCity = scanner.next();
        String arrivalCity = scanner.next();
        String flightDate = scanner.next();
        double maxLoad = scanner.nextDouble();
        Flight flight = new Flight(flightNumber, departureCity, arrivalCity, flightDate, maxLoad);

        // 输入订单信息
        int orderId = scanner.nextInt();
        String orderDate = scanner.next();
        String senderAddress = scanner.next();
        String senderName = scanner.next();
        String senderPhone = scanner.next();
        String recipientAddress = scanner.next();
        String recipientName = scanner.next();
        String recipientPhone = scanner.next();
        Order order = new Order(orderId, orderDate, senderAddress, senderName, senderPhone,
                recipientAddress, recipientName, recipientPhone);

        for (Cargo cargo : cargoList) {
            order.addCargo(cargo);
        }

        if (order.getTotalWeightFormatted() > flight.getMaxLoad()) {
            System.out.println("The flight with flight number: " + flight.getFlightNumber() + " has exceeded its load capacity and cannot carry the order.");
        } else {
            System.out.println("客户:" + customer.getName() + "(" + customer.getPhone() + ")订单信息如下:");
            System.out.println("-----------------------------------------");
            System.out.println("航班号:" + flight.getFlightNumber());
            System.out.println("订单号:" + order.getOrderId());
            System.out.println("订单日期:" + order.getOrderDate());
            System.out.println("发件人姓名:" + order.getSenderName());
            System.out.println("发件人电话:" + order.getSenderPhone());
            System.out.println("发件人地址:" + order.getSenderAddress());
            System.out.println("收件人姓名:" + order.getRecipientName());
            System.out.println("收件人电话:" + order.getRecipientPhone());
            System.out.println("收件人地址:" + order.getRecipientAddress());
            System.out.println("订单总重量(kg):" + order.getTotalWeightFormatted());
            System.out.println("微信支付金额:" + order.getTotalFreightFormatted());

            System.out.println("\n货物明细如下:");
            System.out.println("-----------------------------------------");
            System.out.println("明细编号\t货物名称\t计费重量\t计费费率\t应交运费");
            for (int i = 0; i < cargoList.size(); i++) {
                Cargo cargo = cargoList.get(i);
                System.out.println((i + 1) + "\t" + cargo.getName() + "\t" + cargo.getChargeableWeightFormatted() + "\t" + cargo.getRateFormatted() + "\t" + cargo.getCalculateFreightFormatted());
            }
        }
    }
}
输入
点击查看代码
10001
郭靖
13807911234
南昌航空大学
2
101
发电机
80
60
40
80
102
信号发生器
55
70
60
45
MU1234
昌北国际机场
大兴国际机场
2025-04-22
1000
900001
2025-04-22
南昌大学
洪七公
18907912325
北京大学
黄药师
13607912546
输出
点击查看代码
客户:郭靖(13807911234)订单信息如下:
-----------------------------------------
航班号:MU1234
订单号:900001
订单日期:2025-04-22
发件人姓名:洪七公
发件人电话:18907912325
发件人地址:南昌大学
收件人姓名:黄药师
收件人电话:13607912546
收件人地址:北京大学
订单总重量(kg):125.0
微信支付金额:3350.0

货物明细如下:
-----------------------------------------
明细编号	货物名称	计费重量	计费费率	应交运费
1	发电机	80.0	25.0	2000.0
2	信号发生器	45.0	30.0	1350.0
  1. Cargo 类方法分析
    核心业务方法
    calculateVolumeWeight()
    功能:根据公式 体积重量 = (长×宽×高)/6000 计算货物的体积重量。
    设计:单一职责原则的体现,专注于体积重量计算。
    getChargeableWeight()
    功能:比较实际重量和体积重量,取较大值作为计费重量。
    设计:依赖 calculateVolumeWeight(),符合合成复用原则。
    getRate()
    功能:根据计费重量分阶段计算费率(如 <20kg 为 35 元 /kg)。
    设计:采用条件判断实现费率阶梯,若未来新增费率档位,需修改代码,违反开闭原则。
    calculateFreight()
    功能:计算单件货物的运费(计费重量 × 费率)。
    设计:复用已有方法,符合单一职责。
    辅助方法
    getXXFormatted()
    功能:将计算结果四舍五入到 1 位小数。
    设计:分离格式化逻辑,避免污染核心计算方法。

  2. Flight 类方法分析
    getFlightNumber() / getMaxLoad()
    功能:获取航班基本信息(航班号、最大载重量)。
    设计:简单的 getter 方法,符合单一职责。

  3. Order 类方法分析
    核心业务方法
    addCargo(Cargo cargo)
    功能:添加货物到订单,并更新总重量。
    设计:组合 Cargo 对象,符合合成复用原则。
    calculateTotalFreight()
    功能:累加所有货物的运费,计算订单总费用。
    设计:遍历货物列表并调用 Cargo.calculateFreight(),符合单一职责。
    数据获取方法
    getXXFormatted()
    功能:获取格式化后的订单总重量和总运费。
    设计:复用计算逻辑并应用格式化,避免重复代码。

  4. Customer 类方法分析
    getName() / getPhone()
    功能:获取客户基本信息(姓名、电话)。
    设计:简单的 getter 方法,符合单一职责。

  5. AirCargoSystem 类方法分析
    主方法 main(String[] args)
    功能:程序入口,处理用户输入、业务逻辑和输出结果。
    设计问题:
    违反单一职责:包含输入处理、订单验证、结果输出等多项职责。
    缺乏封装:大量逻辑直接写在 main 方法中,可维护性差。
    示例:

点击查看代码
// 输入处理与业务逻辑耦合
if (order.getTotalWeightFormatted() > flight.getMaxLoad()) {
    System.out.println("航班超载...");
} else {
    // 输出订单信息
}

设计原则遵循情况总结

1.单一职责原则
优点:多数类的方法专注于单一功能(如 Cargo 类的计算方法)。
不足:AirCargoSystem.main() 承担过多职责。

2.开闭原则
不足:Cargo.getRate() 使用条件判断,新增费率需修改原有代码。
改进建议:使用策略模式或工厂模式封装费率计算逻辑。

3.合成复用原则
优点:Order 类通过组合 Cargo 对象实现功能复用。

改进建议

1.重构 AirCargoSystem.main()
将输入处理、业务验证和输出逻辑拆分为独立方法或类。
示例:

点击查看代码
private static Order createOrderFromInput(Scanner scanner) {
    // 封装输入逻辑
}

private static void validateOrder(Order order, Flight flight) {
    // 封装验证逻辑
}

2.优化费率计算(开闭原则)
使用策略模式:

点击查看代码
interface RateStrategy {
    double calculateRate(double weight);
}

class TieredRateStrategy implements RateStrategy {
    // 实现分阶段费率计算
}

3.增强错误处理
添加输入验证(如日期格式、重量合法性),避免程序崩溃。

4.提高代码复用性
将格式化逻辑(如 getXXFormatted())提取为工具类方法。


第二题源码

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

class Order {
    private String customerType;
    private String customerId;
    private String customerName;
    private String customerPhone;
    private String customerAddress;
    private int cargoCount;
    private Cargo[] cargos;
    String flightNumber;
    private String departureAirport;
    private String arrivalAirport;
    private String flightDate;
    private double maxFlightWeight;
    private String orderId;
    private String orderDate;
    private String senderAddress;
    private String senderName;
    private String senderPhone;
    private String receiverAddress;
    private String receiverName;
    private String receiverPhone;
    private String paymentMethod;
    private String paymentMethodChinese; // 新增:中文支付方式

    public Order(Scanner input) {
        this.customerType = input.nextLine();
        this.customerId = input.nextLine();
        this.customerName = input.nextLine();
        this.customerPhone = input.nextLine();
        this.customerAddress = input.nextLine();
        input.nextLine();

        // 错误处理:读取 cargoCount 并确保是数字
        while (true) {
            try {
                this.cargoCount = Integer.parseInt(input.nextLine());
                break;  // 如果成功读取数字,则跳出循环
            } catch (NumberFormatException e) {
                System.out.println("请输入有效的货物数量!");
            }
        }

        this.cargos = new Cargo[this.cargoCount];
        for (int i = 0; i < this.cargoCount; i++) {
            input.nextLine();
            this.cargos[i] = new Cargo(input);
        }

        this.flightNumber = input.nextLine();
        this.departureAirport = input.nextLine();
        this.arrivalAirport = input.nextLine();
        this.flightDate = input.nextLine();

        while (true) {
            try {
                this.maxFlightWeight = Double.parseDouble(input.nextLine());
                break;
            } catch (NumberFormatException e) {
                System.out.println("请输入有效的最大航班重量!");
            }
        }

        this.orderId = input.nextLine();
        this.orderDate = input.nextLine();
        this.senderAddress = input.nextLine();
        this.senderName = input.nextLine();
        this.senderPhone = input.nextLine();
        this.receiverAddress = input.nextLine();
        this.receiverName = input.nextLine();
        this.receiverPhone = input.nextLine();
        this.paymentMethod = input.nextLine();
        this.paymentMethodChinese = convertPaymentMethodToChinese(this.paymentMethod);
    }

    private String convertPaymentMethodToChinese(String paymentMethod) {
        switch (paymentMethod) {
            case "ALiPay":
                return "支付宝";
            case "WeChatPay":
                return "微信支付";
            case "Cash":
                return "现金";
            case "BankTransfer":
                return "银行转账";
            default:
                return paymentMethod; // 如果不认识,保持原样
        }
    }

    public double getTotalWeight() {
        double totalWeight = 0;
        for (Cargo cargo : cargos) {
            totalWeight += cargo.getBillableWeight();
        }
        return totalWeight;
    }

    public boolean isExceedMaxWeight() {
        return getTotalWeight() > maxFlightWeight;
    }

    public void displayOrderInfo() {
        System.out.println("客户:" + customerName + "(" + customerPhone + ")订单信息如下:");
        System.out.println("-----------------------------------------");
        System.out.println("航班号:" + flightNumber);
        System.out.println("订单号:" + orderId);
        System.out.println("订单日期:" + orderDate);
        System.out.println("发件人姓名:" + senderName);
        System.out.println("发件人电话:" + senderPhone);
        System.out.println("发件人地址:" + senderAddress);
        System.out.println("收件人姓名:" + receiverName);
        System.out.println("收件人电话:" + receiverPhone);
        System.out.println("收件人地址:" + receiverAddress);
        System.out.printf("订单总重量(kg):%.1f\n", getTotalWeight());

        double totalAmount = calculateTotalAmount();
        // 修改:使用中文支付方式
        System.out.printf(paymentMethodChinese + "支付金额:%.1f\n", totalAmount);
    }

    public double calculateTotalAmount() {
        double totalAmount = 0;
        for (Cargo cargo : cargos) {
            totalAmount += cargo.calculateFreight(customerType);
        }
        return totalAmount;
    }

    public void displayCargoDetails() {
        System.out.println("货物明细如下:");
        System.out.println("-----------------------------------------");
        System.out.println("明细编号 货物名称 计费重量 计费费率 应交运费");
        int id = 1;
        for (Cargo cargo : cargos) {
            System.out.printf("%d %s %.1f %.1f %.1f\n", id++, cargo.getName(),
                    cargo.getBillableWeight(), cargo.getRate(), cargo.calculateFreight(customerType));
        }
    }
}

class Cargo {
    private String name;
    private double width;
    private double length;
    private double height;
    private double weight;
    private double volumeWeight;
    private double billableWeight;
    private double rate;

    public Cargo(Scanner input) {
        this.name = input.nextLine();

        // 错误处理:确保读取宽度、长度、高度和重量时是有效的数字
        this.width = readDouble(input, "请输入有效的宽度!");
        this.length = readDouble(input, "请输入有效的长度!");
        this.height = readDouble(input, "请输入有效的高度!");
        this.weight = readDouble(input, "请输入有效的重量!");

        // 计算体积重量
        this.volumeWeight = (width * length * height) / 6000;
        this.billableWeight = Math.max(weight, volumeWeight);

        // 根据货物名称设置费率(临时解决方案)
        if (name.contains("发电机")) {
            this.rate = 40.0;
        } else if (name.contains("信号发生器")) {
            this.rate = 50.0;
        } else {
            this.rate = 30.0; // 默认费率
        }
    }

    private double readDouble(Scanner input, String errorMessage) {
        while (true) {
            try {
                return Double.parseDouble(input.nextLine());
            } catch (NumberFormatException e) {
                System.out.println(errorMessage);
            }
        }
    }

    public String getName() {
        return name;
    }

    public double getBillableWeight() {
        return billableWeight;
    }

    public double getRate() {
        return rate;
    }

    public double calculateFreight(String customerType) {
        double baseFreight = billableWeight * rate;
        double discount = customerType.equals("Individual") ? 0.9 : 0.8;
        return baseFreight * discount;
    }
}

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

        // 创建订单对象
        Order order = new Order(input);

        // 检查航班是否超载
        if (order.isExceedMaxWeight()) {
            System.out.println("The flight with flight number: " + order.flightNumber + " has exceeded its load capacity and cannot carry the order.");
        } else {
            order.displayOrderInfo();
            order.displayCargoDetails();
        }

        input.close();
    }
}

posted on 2025-05-25 12:04  23201836-高歌  阅读(36)  评论(0)    收藏  举报

导航