航空器配载与货运管理系统——三次作业总结

一、前言
本阶段共完成了三次迭代作业,逐步构建了一个完整的航空器配载与货运管理系统。从第一次作业的基础货物装载,到第二次作业的多货舱管理,再到第三次作业的配平计算,每一次迭代都在前一版本的基础上增加了新的业务需求和技术挑战。

知识点覆盖:三次作业涵盖了Java面向对象编程的核心概念,包括单一职责原则(SRP)、类与对象的设计、ArrayList的使用、排序算法的实现、输入合法性校验、以及基于物理公式的业务计算。第三次作业还引入了力矩计算和重心百分比等航空专业领域的知识。

题量与难度:第一次作业代码量约150行,难度适中,主要考察基本的类设计和排序;第二次,第三次作业代码量约300行,难度最高,需要综合运用前面的成果,并新增旅客管理、力矩计算等模块。整体来说,三次作业的难度呈阶梯式上升,设计上保持了良好的延续性。

个人完成情况:三次作业均按要求完成,有部分测试点未通过。代码设计严格遵循单一职责原则,未使用继承和多态。

二、设计与分析
2.1 第一次作业——基础货运配载
第一次作业要求实现一个基础的航班货运配载模块。系统需要记录航班的基本信息(航班号、最大起飞重量、最大业载重量),地勤人员可以按照货物重量从高到低向该航班添加货物,系统实时计算当前已装载的总重量并判断是否超载。
排序算法采用冒泡排序(降序),时间复杂度O(n²),对于货物件数不超过100的情况性能足够。每次添加货物后实时计算总重量,通过LoadingChecker判断是否超过最大载重。
整体结构清晰,每个类的职责单一,符合SRP要求。排序算法独立封装在CargoManager中,方便后续替换为其他排序策略。
复杂度分析
0aee73c65d0fdd3105812de6d7293d13

以下为类图

屏幕截图 2026-05-18 211734

2.2 第二次作业——多货舱管理与重量排序装载
第二次作业在第一次的基础上进行了扩展:飞机不再只有一个货舱,而是分为多个货舱(如前舱、后舱等)。每个货舱有独立的最大载重和固定数量的装载位置、。地勤人员需要按照货物重量从高到低的顺序,将每件货物选择放入某个货舱,系统需实时检查该货舱是否超载。
这次迭代最关键的改进是引入了CargoCompartment类,将货舱作为独立的管理单元。货舱与其位置是组合关系(创建时内部生成Position列表),货舱与装载的货物是聚合关系(Cargo可独立存在)。这种设计符合面向对象的基本原则。
排序逻辑:、使用选择排序对货物按重量降序排列,同等重量的货物保持输入顺序(稳定排序)。装载时依次尝试装入目标货舱,若该货舱剩余容量不足则装载失败并给出提示。
复杂度分析
914df8b7e6eb30ac4aa67fa86aa16158
以下为类图
屏幕截图 2026-05-18 211700

2.3 第三次作业——配平计算
第三次作业是难度最大的一次迭代。在第二次作业的基础上,新增了旅客管理(乘客体重+行李)和载重平衡计算功能。所有装载项(旅客、前舱货物、后舱货物)都有其对应的力臂,需要计算全机重心位置并判断是否在安全范围内。
核心计算公式

旅客总重量 = Σ (75.0kg + 行李重量)
旅客总力矩 = 旅客总重量 × 18.0m
货舱力矩 = Σ (货舱重量 × 对应力臂) // 前舱12.0m,后舱22.0m
全机总重量 = 40000.0kg + 旅客总重量 + 货舱总重量
全机总力矩 = 40000.0×16.25 + 旅客总力矩 + 货舱总力矩
实际重心 = 全机总力矩 / 全机总重量
CG% MAC = ((实际重心 - 15.0) / 5.0) × 100%
复杂度分析
7ac527d083409fdf935241f30fabf2f1
以下为类图
屏幕截图 2026-05-18 211710

三、采坑心得
3.1 第一次作业——排序算法选择
在第一次实现时,我一开始想用Collections.sort()方法,但题目明确禁止使用。于是手写了冒泡排序。冒泡排序虽然简单,但要注意内层循环的边界条件:j < n - 1 - i,这样可以避免重复比较已排好序的元素。

教训:手写排序时务必注意边界条件,建议先用小数据测试验证。

3.2 第二次作业——货舱与货物的关系
第二次作业要求货舱与位置是组合关系(货舱创建时内部生成Position列表),货舱与货物是聚合关系(Cargo可独立存在)。一开始我混淆了这两种关系,在CargoCompartment构造器中忘记初始化positions列表。

教训:理解UML类图中的关系符号至关重要——实心菱形表示组合(生命周期一致),空心菱形表示聚合。

3.3 第三次作业——输入校验的时机
第三次作业要求对输入数据进行合法性验证,发现非法输入立即停止程序。我设计了InputValidator类集中处理校验,但一开始在校验顺序上出了问题。

关键点:输入数据的合法性校验必须在数据被使用之前完成。一旦发现非法数据,立即System.exit(0)终止程序,避免后续计算使用非法值。

3.4 第三次作业——空机重力臂的精度问题
题目给定空机重力臂为16.25 m,输出样例中显示为16.3 m(保留一位小数)。一开始我直接使用System.out.printf("%.1f", 16.25),得到16.3,符合要求。但需要注意四舍五入的规则:16.25保留一位小数,Java默认采用四舍五入(round half up),得到16.3。

3.5 输入读取的常见陷阱
Java中使用Scanner读取混合类型数据时,nextLine()会读取上次输入后的换行符。虽然本次作业使用next()和nextDouble()可以避免这个问题,但在读取字符串时仍需注意。
四、改进建议
4.1 引入配置管理
当前代码中所有常量(如空机重量40000.0kg、力臂参数、MAC参数等)都硬编码在类中。建议创建一个Config类集中管理这些常量,便于后续修改和维护。

4.2 货舱力臂的通用化处理
第三次作业中,前舱和后舱的力臂是硬编码的(12.0m和22.0m)。如果后续增加更多货舱,这种方式将无法扩展。建议在CargoCompartment类中增加liBi属性,在创建货舱时传入力臂值。

4.3 增加异常处理机制
当前代码使用System.exit(0)直接终止程序,这种方式过于粗暴。建议使用自定义异常类,在main方法中统一捕获处理,使程序更加健壮。

4.4 排序算法可配置化
当前排序算法直接写在LoadDispatcher类中。可以考虑将排序策略设计为可插拔的形式,虽然题目禁止使用多态和接口,但可以使用策略模式的思想,通过不同的方法实现不同的排序算法。

4.5 增加单元测试
在开发过程中,建议为每个核心类编写单元测试。例如为WeightBalanceCalculator编写测试用例,验证各种输入组合下的重心计算结果是否正确。

五、总结
5.1 学习成果
通过这三次迭代作业,我收获颇丰:

深入理解单一职责原则(SRP):每个类只负责一项职责,这使得代码易于理解、测试和维护。例如LoadDispatcher只负责排序和查找,WeightBalanceCalculator只负责计算,职责边界清晰。

掌握类间关系设计:组合关系(货舱与位置)、聚合关系(货舱与货物)、依赖关系(计算器与航班),这些关系的正确使用是面向对象设计的基础。

手写排序算法的能力:在不能使用Collections.sort()的情况下,熟练掌握了冒泡排序和选择排序的实现。

输入合法性校验的重要性:在任何数据被使用之前进行校验,是程序鲁棒性的第一道防线。

业务逻辑与输出分离:BalanceReport类专门负责输出格式化,将计算逻辑与展示逻辑分离,降低了耦合度。

5.2 待改进之处
测试不够充分:没有通过所有pta测试点,没有编写系统的单元测试。对于复杂计算(如重心百分比),应该准备多组测试数据验证正确性。

代码复用可以更好:三次作业中有些代码(如输入处理)存在重复,可以进一步抽象复用。

对航空业务的理解:虽然实现了计算公式,但对重心、力矩等航空概念的理解还不够深入,这可能影响对业务逻辑的准确把握。
5.3 对课程的建议
增加代码审查环节:可以组织同学之间相互阅读代码,学习优秀的设计思路,同时也能发现自己的不足。

提供参考答案的类图:每次作业结束后,可以提供一份参考设计的类图,让同学对比自己的设计,找出差异和改进方向。

5.4 心得体会
这三次作业让我真正体会到了“迭代开发”的含义。从简单到复杂,每一步都在前一版本的基础上增加新功能,而不是推翻重来。这种开发方式贴近实际工程,让我学会了如何设计可扩展的系统架构。

第三次作业的配平计算是一个亮点,它将物理公式与编程结合,让我感受到了编程在工程领域的实际应用价值。当看到程序输出的重心百分比和评估结果时,确实有一种真正完成了任务的成就感。

最后,感谢老师精心设计的题目,我之后也会继续精进技术,让自己能够在之后的作业中能拿到更高的分

posted @ 2026-05-18 21:23  结城梨抖  阅读(7)  评论(0)    收藏  举报