航空货运

Posted on 2025-05-20 19:39  yumi12138  阅读(19)  评论(0)    收藏  举报

一、前言
 

第 8 次题目集围绕基础编程与功能拓展展开。第一题 “点线面重构” 作为基础题型,核心在于严格遵循题目给定的类图进行代码实现,将类图中的类、属性及关系精准转化为代码。实际操作中,主函数的设计是关键,需合理完成各类对象的创建、存储以及结果输出。第二题 “雨刷程序功能扩展设计”,在原有功能基础上新增雨刷,要求运用接口和抽象类进行设计,考验对面向对象设计原则的理解与运用,通过抽象共性行为、定义接口规范,实现代码的扩展性与可维护性。第三题 “航空货运管理系统”,虽然输入信息繁杂,涵盖客户、货物、航班等多方面内容,但计算逻辑清晰,重点在于将业务流程转化为代码逻辑,实现运费计算与订单信息处理功能。
第 9 次题目集进一步深化面向对象编程的应用。第一题需深入理解类图中各类的含义与关系,精准把握类的职责与交互逻辑,是对类图解读能力的直接考察。第二题 “容器类与泛型”,重点在于掌握容器类的使用及泛型特性,通过泛型实现类型安全,同时实现容器的增删遍历等操作,提升数据管理的灵活性与效率。第三题则是对第 8 次题目集航空货运管理系统的拓展,引入不同类型的货物与客户类型,增加了费率计算的复杂性,需要在原有代码基础上,结合新的业务规则进行功能扩展,全面考查代码的扩展性和对复杂业务逻辑的处理能力 。
二、设计与分析
  • 第八次题目集

    1.点线面问题重构
    这道题把将Point类和Line类作为Element类的子类,将Element设置为抽象类,重写display() 方法,主函数中调用
// 使用 Element 引用实现多态
        Element element;

        element = p1;//起点Point
        element.display();
        System.out.println();

        element = p2;//终点Point
        element.display();
         System.out.println();

        element = line;//线段
        element.display();

        element = plane;//面
        element.display();
  • 用父类引用统一管理子类对象,代码简洁。
  • 支持后续新增子类(如Circle),无需修改遍历逻辑。
    2.雨刷重构的设计:
    这道题一开始并没有写的很顺畅,我觉得我的代码的复杂度很高这道题用switch来直接选择速度会更好一点,我是用的数组,因为两个表的间歇档位的档位数量不同,所以数组大小也不同。把Agent抽象出来,重写了两个方法
    // 定义 Agent 接口
    interface Agent {
        void dealSpeed();
        void show(String operationType);
    }
    3.航空货运管理系统
    题目说明:
    https://images.ptausercontent.com/499d204b-fcef-4610-a9ca-c8fbf5e346d9.pdf
    本次题目模拟某客户到该航空公司办理一次货运业务的过程:
    航空公司提供如下信息:
    航班信息(航班号,航班起飞机场所在城市,航班降落机场所在城市,航班
    日期,航班最大载重量)
    客户填写货运订单并进行支付,需要提供如下信息:
    客户信息(姓名,电话号码等)
    货物信息(货物名称,货物包装长、宽、高尺寸,货物重量等)
    运送信息(发件人姓名、电话、地址,收件人姓名、电话、地址,所选航班号,订单日期)
    支付方式(支付宝支付、微信支付)
    注:一个货运订单可以运送多件货物,每件货物均需要根据重量及费率单独计费。
    程序需要从键盘依次输入填写订单需要提供的信息,然后分别生成订单信息报表及货物明细报表
    这道题目我把运输类定义为父类Trans,order类整合所有的信息,
    // 订单类(整合所有信息)
    class Order extends Trans {
        private String orderId;
        private Customer customer;
        private List<Cargo> cargoList;
        private Flight flight;
    
        public Order(String orderId, String orderDate, Customer customer,
                     List<Cargo> cargoList, Flight flight, Trans transInfo) {
            super(transInfo.getSenderName(), transInfo.getSenderPhone(), transInfo.getSenderAddress(),
                    transInfo.getReceiverName(), transInfo.getReceiverPhone(), transInfo.getReceiverAddress(),
                    transInfo.getFlightNum(), transInfo.getOrderDate());
            this.orderId = orderId;
            this.customer = customer;
            this.cargoList = cargoList;
            this.flight = flight;
        }
    
        // Getter 方法
        public String getOrderId() {
            return orderId;
        }
    
        public Customer getCustomer() {
            return customer;
        }
    
        public List<Cargo> getCargoList() {
            return cargoList;
        }
    
        public Flight getFlight() {
            return flight;
        }
    }
    这个货物运费加和时运用的方法有点高级,我们可以换成下一种
    return cargoList.stream()          // 将列表转换为Stream流
                   .mapToDouble(Cargo::cal_Money)  // 映射每个货物到其费用
                   .sum();             // 累加所有费用
    private static double calculateTotalCost(List<Cargo> cargoList) {
        double total = 0.0;
        for (int i = 0; i < cargoList.size(); i++) {
            Cargo cargo = cargoList.get(i);
            total += cargo.cal_Money(); // 累加单件费用
        }
        return total;
    }


  • 代码行数(Lines):465
  • 语句数量(Statements):134
  • 代码结构相关(Percent Branch Statements):分支语句所占百分比,为 0.0% ,反映代码中使用如if - else 、switch等分支结构的比例情况。
  • 方法调用语句数量(Method Call Statements):8
  • 含注释的代码行所占百分比(Percent Lines with Comments):1.9%
  • 类和接口的数量(Classes and Interfaces):4
  • 平均每个类的方法数(Methods per Class):13.50
  • 平均每个方法的语句数(Average Statements per Method): 2.26
  • 最复杂方法所在的行号(Line Number of Most Complex Method): 103
  • 最复杂方法的名称(Name of Most Complex Method):Normal
  • 最大复杂度(Maximum Complexity): 1
    //衡量方法逻辑复杂程度,数值越高逻辑越复杂

平均复杂度(Average Complexity):1.0
类图:

分析:

面向对象设计思想明确

    • 代码通过多个类(TransCargoCustomerFlightOrder)封装不同领域的概念,符合单一职责原则。
    • 使用继承(如NormalCargo继承Cargo)和接口(PaymentMethod)实现多态,例如支付方式可扩展(支付宝、微信支付),符合开闭原则。
模块化结构清晰
    • 类职责划分明确:
      • Trans负责运输信息,Cargo处理货物计算,Flight管理航班信息,Order整合所有数据。
      • PaymentMethod接口分离支付逻辑,便于后续扩展其他支付方式(如银联支付)。
数据校验与业务逻辑分离
    • main方法中检查货物总重量是否超过航班载重,逻辑清晰,避免业务逻辑混入类内部。
代码复用性较好
    • Cargo类的calWeightcal_Money方法可被所有子类继承,减少重复代码。
  • calculateTotalCost静态方法复用货物费用计算逻辑。

第九次习题集
1.魔方问题:
类图:

弄明白一个类是每一块体积,下面的类是整个的魔方体积
2.点线面问题的重构
主要是多加了一个容器类和主函数的变化
3.航空货运管理系统
https://images.ptausercontent.com/b9cec79b-8012-4901-843e-3d48f27d28a6.pdf

  • 代码行数(Lines):516
  • 语句数量(Statements):214
  • 代码结构相关(Percent Branch Statements):分支语句所占百分比,为 2.3% ,反映代码中使用如if - else 、switch等分支结构的比例情况。
  • 方法调用语句数量(Method Call Statements):45
  • 含注释的代码行所占百分比(Percent Lines with Comments):9.1%
  • 类和接口的数量(Classes and Interfaces):9
  • 平均每个类的方法数(Methods per Class):6.22
  • 平均每个方法的语句数(Average Statements per Method): 1.43
  • 最复杂方法所在的行号(Line Number of Most Complex Method): 16
  • 最复杂方法的名称(Name of Most Complex Method):ALiPay
  • 最大复杂度(Maximum Complexity): 1
    //衡量方法逻辑复杂程度,数值越高逻辑越复杂
    类图:

三、踩坑心得

航空货运系统主要是添加了不同的货物类,客户类


我定义了三种不同货物的子类 ,Normal/Expedite/Dangerous重写费率和运费方法,定义了两种客户类型Individual/Corporate,加上获取折扣率的方法,因为继承客户类,直接在Order订单类中直接 * customer.getDiscountRate();算出单件运费,货物类相同

主要是在考虑主函数如何输入,如何创建对象

Customer customer;
                    if ("Individual".equals(kind)) {
                        customer = new individualCustomer(customerId, customerName, customerPhone, customerAddress);
                    } else if ("Corporate".equals(kind)) {
                        customer = new corporateCostomers(customerId, customerName, customerPhone, customerAddress);
                    } else {
                        customer = new Customer(customerId, customerName, customerPhone, customerAddress);
                    }
//---------------------------------------------------------------------
  // 根据货物类型创建对应实例(修复构造函数调用)
                        switch (kindCargo) {
                            case "Normal":
                                cargoList.add(new NormalCargo(id, name, length, width, height, weight));
                                break;
                            case "Expedite":
                                cargoList.add(new ExpediteCargo(id, name, length, width, height, weight));
                                break;
                            case "Dangerous":
                                cargoList.add(new DangerousCargo(id, name, length, width, height, weight));
                                break;
                            default:
                                throw new IllegalArgumentException("无效的货物类型");
                        }

                    }

另外在提交之后发现答案错误,
最后发现是在表格中的实际重量打印成了质量重量,把getWeight();改成calWeight();之后答案正确
四、改进建议
代码中注释含量明显较少,可能需要添加更为详细的代码注释,Order 类职责过多,拆分计算费用的逻辑到单独的服务类。可以将 Customer 改为接口或抽象类,让 Order 依赖抽象而非具体类;使用组合代替继承(Order 和 Trans 的关系)。抽象接口(ICustomerPaymentMethod)的使用降低高层模块对具体类的依赖。
五、总结  
 通过这两次题目集的实践,我系统掌握了面向对象编程的核心思想与设计原则。在类的设计上,接口(如PaymentMethod)规范行为,通过继承与多态实现代码复用(如不同货物类型的运费计算)。理解了单一职责原则的重要性,例如将Order的职责拆分为数据存储与费用计算,提升代码内聚性。 深刻体会开闭原则“对扩展开放、对修改封闭”的优势。同时,通过输入校验、重量超限检查等细节,增强了代码健壮性意识。 此外,认识到命名规范、注释完整性对代码可读性的影响,以及组合优于继承的设计原则(如`Order`与`Trans`的关系)。

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3