飞机货物配载作业集代码分析与设计总结
前言
在本学期的 Java 面向对象课程学习中,我围绕飞机货物配载与载重平衡这个主题,完成了三次循序渐进的编程作业。三次作业难度由浅入深,知识点层层递进,题量也随着功能增多不断加大,从简单的基础功能实现,慢慢过渡到综合性较强的系统开发,让我一步步熟悉了面向对象编程的基本思路。
作业集 1 为入门基础题,题量较小,主要考察类的封装、对象创建、数组使用、简单选择排序、基础输入输出,实现航班、货物基础信息管理与货物装载超载判断,整体逻辑简单,类结构划分基础,侧重熟悉面向对象基本语法;
作业集 2 为进阶应用题,题量中等,引入ArrayList 动态集合、多货舱管理、货物调度分发、状态校验,在基础装载功能上增加货舱划分、货物按目标货舱分类装载、多重超载判定,考察集合使用、类之间调用关系、业务逻辑分层,难度较第一次明显提升;
作业集 3 为综合压轴题,题量最大、功能最完整,集成旅客与行李管理、多货舱位置建模、冒泡排序、起飞重量 / 业载限制、力矩计算、重心百分比(% MAC)、重心安全区间校验,实现了一套完整的飞机载重平衡系统,综合考察封装继承思想、复杂类依赖关系、数学模型落地、业务边界判断,逻辑复杂度高,代码耦合与结构设计成为重点难点。
为了更清楚地看到自己三次作业的代码问题,我用 SourceMonitor 工具统计了代码行数、复杂度等指标,又用 PowerDesigner 画出 UML 类图,分析类之间的结构关系。通过本次整体复盘,我总结了自己在代码编写、结构设计上的不足,也梳理了学习过程中的收获,为后续面向对象编程打下基础。
设计与分析
第一次作业:
题目要求:这次作业是航空配载系列的第一道题,难度中等,主要让我们做一个基础航班货物装载系统。
需要实现的功能有:
1、输入航班号、航班最大载重、货物数量。
2、输入多件货物的名称和重量。
3、把货物按重量从大到小排序。
4、输出排序后的货物信息。
5、计算总重量,判断是否超载。
6、输出总重量、最大载重,最后输出 “正常” 或 “严重超载”。
实现方式:我一共分了5 个类来写,每个类只负责自己的功能,完全遵守单一职责原则。
1、Flight 类
存航班号、最大载重,只提供获取数据的方法,不做其他逻辑。
2、Cargo 类
存货物名称、重量,提供获取名称和重量的方法。
3、CargoSorter 类
只有一个排序方法,使用选择排序把货物按重量从大到小排。
这是一个工具类,只负责排序,不参与其他业务。
4、LoadManifest 类
管理货物数组,记录装了哪些货物,计算总重量。
它关联航班,用来判断有没有超载。
5、Main 类
程序入口,处理输入、调用各个类、输出结果。
所有流程调度都在这里完成。
代码规模
第一次作业代码如下图。

类图

Bug分析
公测
自己测试的时候,发现Scanner 输入会吞回车。
在用nextInt()读取货物数量后,直接用nextLine()读货物名称,会直接读到空字符串,导致货物名称读取失败。
原因是读取数字后留下的换行符被下一行接收了。
解决办法:在读取数字后多加一句scanner.nextLine(),专门接收换行符,后面就能正常读取名称。
互测
和同学互相测试时,发现我货物排序方向搞反了。
我最开始写的是从小到大升序排序,但题目要求按重量从大到小降序输出,直接导致输出顺序和样例完全不一样。
后来把排序里的大于小于条件改过来,就正常了。
测试方法
这次作业我主要用手动黑盒测试,自己设计几组简单输入测试,同时和室友互相测代码,做了公测和互测,检查输入、排序、输出、边界情况有没有问题。
第二次作业:
题目要求:这是第二次航空配载作业,在第一次基础上做了升级,难度比第一次高。
这次不再是单一货舱,分成了前货舱、后货舱两个货舱,每个货舱有自己的最大载重,货物需要指定装进哪个货舱。
需要实现的功能:
输入航班基础信息,还有前后两个货舱的行数、列数、最大载重。
输入旅客人数和行李重量,统计旅客总重量。
输入多件货物,每件指定要装的目标货舱。
货物按重量从大到小排序,优先装入目标货舱。
每个货舱判断是否超载,同时还要判断整个航班总重量是否超过最大起飞重量、最大业载。
输出每个货舱装载情况、航班整体状态。
类设计依旧要遵循单一职责原则,一个类只做一件事。
实现方式:这次我拆分了 7 个类,每个类职责清晰,没有混在一起写:
Position 类:用来记录货舱里每个位置的行列信息,只保存位置数据。
Cargo 类:保存货物编号、重量、目标货舱 ID,只做数据存储。
CargoCompartment 类:管理单个货舱,存最大载重、货物列表,实现添加货物、计算当前重量、判断是否超载。
Flight 类:管理整个航班,包含多个货舱、旅客信息,计算航班总重量,判断整体是否超载。
LoadDispatcher 类:调度货物,实现货物排序、分发装载,是工具类。
Passenger 类:保存旅客姓名、自身标准重量和行李重量。
Main 主类:程序入口,处理所有输入,调用各个类,输出最终结果。
代码规模

类图

第三次作业
题目要求:第三次是整个航空配载系列的综合压轴题,在前面两次作业的基础上做了最大程度的拓展,完整模拟真实航班配载和重心平衡计算。
除了之前的航班、多货舱、货物、旅客行李装载功能之外,新增了力矩、重心、重心百分比、安全区间校验等航空专业计算。
主要功能要求:
输入前后货舱的行列、最大载重,录入旅客信息和每件货物信息,指定装载货舱。
货物按重量降序排序后装载,每个货舱单独判断是否超载。
统计旅客总重量、前后货舱货物重量。
计算空机重量力矩、旅客力矩、前后货舱力矩,算出总力矩、起飞总重量。
计算飞机实际重心 CG,再算出重心占平均气动弦长的百分比 % MAC。
判断重心是否在安全区间内,输出配载是否安全。
所有类严格遵循单一职责原则,结构分层清晰。
实现方式:这次功能比较多,我一共分了 9 个类来实现,每个类只负责自己的功能:
Position 类:记录货舱位置的行和列,生成位置信息。
Cargo 类:存储货物编号、重量、目标货舱。
CargoCompartment 类:管理单个货舱,实现货物添加、重量统计、输出货舱装载详情。
Flight 类:管理整个航班,管理所有货舱、旅客,计算整体重量,输出航班舱单信息。
LoadDispatcher 类:负责货物排序、调度分发、自动装载货物。
Passenger 类:记录旅客,自带标准体重,加上行李重量算出单人总重。
Luggage 类:单独存储行李重量,和旅客类分开,符合单一职责。
WeightBalanceCalculator 类:专门做重心、力矩、% MAC、安全判断的计算工具类。
Main 主类:程序入口,处理所有输入,调用各个模块,输出完整的载重平衡舱单。
代码规模

类图

踩坑心得
经过这三次航空器配载作业的编写,我踩了很多低级又典型的坑,也慢慢从一开始的手忙脚乱,变得能更严谨地写代码、查 bug。这三次作业层层递进,踩的坑也从基础语法问题,慢慢过渡到逻辑设计和业务细节,每一次踩坑都是一次教训,也让我对 Java 面向对象编程和实际业务开发有了更实在的理解,下面就说说我这三次作业里印象最深的踩坑经历和心得。
第一次作业是基础版,踩的都是最基础的语法和输入输出坑,最让我头疼的就是 Scanner 输入吞回车的问题。一开始我直接用 nextInt () 读取货物数量后,就用 nextLine () 读货物名称,结果每次都读不到名称,输出的货物信息都是空的,调试了好久才发现,是读取数字后留下的换行符被 nextLine () 接收了,导致后续输入全部错乱。后来在每个 nextInt () 后面加了一句 scanner.nextLine () 吸收换行符,才解决了这个问题。另外一个坑就是排序方向搞反了,题目要求货物按重量从大到小排序,我一开始写成了从小到大,自己测试的时候没注意,互测的时候被同学指出来,才发现输出顺序和样例完全不符。这次作业让我明白,基础语法和题目要求一定要盯紧,看似简单的输入输出和逻辑,稍微粗心就会出问题,写完代码一定要先对照样例测试,不能想当然。
第二次作业在第一次的基础上增加了多货舱、旅客管理,难度提升了不少,踩的坑也偏向于逻辑和类设计。最主要的坑是货舱超载判断不严谨,我一开始只判断了单个货舱的重量是否超过自身最大载重,却忽略了题目要求还要判断整个航班的总重量是否超过最大起飞重量和最大业载,导致测试时明明航班总重量超标,却没有输出警告。还有一个坑是 ArrayList 集合的使用不熟练,一开始用数组存储货舱和货物,经常出现数组越界的问题,后来换成 ArrayList 动态集合,虽然解决了越界问题,但又忘记判断集合是否为空,导致遍历的时候出现空指针异常。另外,类设计虽然遵循了单一职责,但类之间的调用关系没理清楚,比如 Flight 类和 CargoCompartment 类的关联的逻辑写得很混乱,导致后续修改和调试特别麻烦。这次作业让我意识到,随着功能增多,逻辑一定要梳理清晰,类之间的调用要规范,而且不能只关注单个功能的实现,还要兼顾整体业务需求,考虑到所有的判断条件。
第三次作业是综合压轴题,新增了力矩、重心计算等航空专业内容,踩的坑主要集中在业务逻辑、数学计算和边界处理上。第一个大坑就是重心计算的公式理解错误,题目给的力矩、重心、% MAC 的计算公式,我一开始没吃透,直接照搬公式却忽略了单位和计算顺序,导致计算出的重心百分比和安全区间判断全部错误,调试了很久,对照题目要求一步步推导公式,才修正了计算逻辑。第二个坑是边界条件考虑不全面,比如货物重量为负数、货舱 ID 输入错误的情况,我一开始没有做判断,导致程序运行报错;还有旅客人数为 0 的情况,也没有做特殊处理,导致总重量计算异常。另外,类的拆分虽然更细,但部分类的职责还是有重叠,比如 WeightBalanceCalculator 类和 Flight 类都有重量计算的相关方法,导致代码冗余,后期修改的时候需要同时修改两个地方,很容易出错。还有一个小坑是输出格式不规范,重心、力矩等数值的小数保留位数没有按照题目要求,导致输出结果和预期不符。
这三次作业踩的坑,总结下来主要是三类:基础语法和输入输出的粗心错误、类设计和逻辑梳理的不严谨、业务需求和专业细节的忽略。通过这三次踩坑,我也总结出了一些经验:第一,写代码前一定要先吃透题目要求,把每个功能点、输出格式、判断条件都梳理清楚,不能急于动手写代码;第二,基础语法要熟练,尤其是输入输出、集合、循环这些常用知识点,避免出现低级错误;第三,类设计要严格遵循单一职责原则,类之间的调用关系要清晰,避免职责重叠和逻辑混乱;第四,写完代码后,不仅要测试正常用例,还要测试边界用例和异常用例,比如数值为 0、负数、空值等情况,尽量提前发现 bug;第五,遇到专业相关的计算,一定要吃透公式和逻辑,不能盲目照搬,必要时可以分步调试,验证每一步的计算结果。
改进建议
通过三次作业的编写,我也发现了自己代码里不少可以优化的地方,总结出几点改进方向。
第一,代码注释太少,很多方法和类没有写注释,后期自己回看或者调试时,理解起来比较费劲,后续写代码会适当加一些简洁注释,提高可读性。
第二,边界条件考虑不够全面,像负数重量、空输入、货舱不存在这类情况处理不完善,之后会提前多考虑异常场景,增加合法性判断。
第三,部分代码可以复用,比如重量计算、格式化输出,重复代码较多,可以提取成工具方法,简化代码结构。
第四,类之间调用逻辑有些复杂,后续设计时会提前画好简单思路,让类的职责更纯粹,耦合更低,方便修改和扩展。
总结
通过这三次航空器配载系统的编程练习,我从基础的面向对象语法,逐步过渡到多类协作、集合使用和专业业务计算,完整完成了从简单货物装载到飞机重心配平的系统开发。
三次作业难度层层递进,我不仅熟练掌握了类的封装、单一职责原则、排序算法、ArrayList 集合等知识点,还学会了处理输入异常、边界条件、多类之间的调用关系。在不断调试、公测互测排查 bug 的过程中,我改掉了粗心、逻辑考虑不全的问题,也理解了代码规范、结构清晰的重要性。
同时我也意识到自身不足,比如注释较少、异常处理不完善、代码复用性不强。后续我会继续养成良好的编程习惯,写代码前理清逻辑,写完多组测试,提升代码质量,为之后更复杂的项目开发打好基础。
浙公网安备 33010602011771号