NCHU_航空器配载与货运管理系统PTA三次迭代作业总结

航班货运装载三次迭代作业总结

前言

本阶段的三次 PTA 作业都围绕航班货运装载来展开。三次作业沿用同一主题,不过约束条件在不断增加。第一次作业去处理基础装载统计。第二次作业把货舱和载重限制加入进来。第三次作业再把配载平衡以及安全判断加入进来。题目的重点已经超出输入输出。内容逐步转到建模、结构组织以及规则表达这些方面。

这一组作业涉及的知识点比较集中,主要包括面向对象建模、输入校验、排序、对象协作、规则封装以及计算逻辑拆分。第一次作业偏基础。第二次作业开始要求模块分工。第三次作业已经接近一个小型业务程序。把三次作业放在一起看,更明显的变化不在代码行数本身。重点在问题规模扩大之后,代码结构还能不能保持清楚。

一、三次作业集的整体认识

三次作业之间的递进关系很清楚。第一次作业只要求读取航班信息以及货物信息,再完成排序和总重量统计。第二次作业不再把货物当作一个简单数组来使用。题目要求货物进入指定货舱,所以程序必须把货舱本身以及整架飞机的承载情况描述出来。第三次作业继续增加限制,判断重点也从“能否装下”转成“装完后是否安全”。

代码规模也能反映这一点。根据源代码统计,第一次作业约 90 行,第二次作业约 296 行,第三次作业约 346 行。类的数量从 6 个增加到 9 个,再增加到 12 个。这个变化说明,问题扩大以后,单靠一个主流程去堆叠逻辑已经不够,还需要借助更多职责明确的类来分担工作。

从学习过程来看,这三次作业的价值不只在单次得分。它还把同一个问题逐步展开。第一次考察基本建模。第二次考察结构拆分。第三次考察规则表达以及可维护性。把三次作业连起来看,更容易暴露设计短板,也更容易看清代码结构对后续迭代的影响。

二、设计与分析

1. 第一次作业:基础装载统计

第一次作业的程序结构比较直接。LoadManifest 负责读取输入。Cargo 用来表示单件货物。Flight 保存航班以及货物集合。CargoSorter 负责进行排序。outPutInfo 负责输出结果。结构虽然简单,不过已经能看出基本分工。输入、处理以及输出没有完全堆在 main 方法中。

这一次建模的核心类是 Flight。总重量计算以及是否超载都属于航班整体属性,把这部分逻辑放在 Flight 中会更合适。这样处理以后,相关行为就回到对象内部,外部函数只保留流程控制。这种写法比把所有判断都写在主函数里更清楚。

代码规模如下:

代码规模

类图如下:

PTA1类图

复杂度分析如下:

类复杂度

从复杂度结果来看,第一次作业里大部分方法都比较简单。Main.main()、Flight.isSafety() 以及几个构造方法的复杂度都不高。相对复杂一些的方法是 LoadManifest.LoadFlight() 和 Flight.getTotalWeight()。前者负责集中读取输入,后者负责遍历数组求和。这和代码结构基本一致。

这次作业的问题也比较明显。CargoSorter 采用了双重循环排序。数据规模扩大以后,效率会下降。outPutInfo 直接访问 Flight 的内部字段,封装也不够充分。第一次作业完成了基本功能,也完成了最初的对象划分,不过整体设计还是比较粗。

2. 第二次作业:多货舱装载调度

第二次作业比第一次复杂很多。程序中新增了 CargoCompartment、Position、InputValidator、LoadDispatcher 等类。问题重点已经不在简单读入和计算。重点变成了一个带约束的装载过程。程序流程包括航班输入、货舱输入、货物输入、重量排序、目标货舱装载以及结果输出。

这次作业的主要改进在类职责划分上。Flight 不再只是保存基础字段,它开始管理多个 CargoCompartment,并且提供 findCompartmentById()、getTotalCargoWeight() 等方法。LoadDispatcher 也被单独抽离出来,专门负责装载调度。这样处理以后,输入逻辑以及装载逻辑就分开了。后续如果修改装载策略,影响范围会小很多。

代码规模如下:

代码规模

类图如下:

PTA2类图

复杂度分析如下:

类复杂度

复杂度报告显示,第二次作业的方法复杂度总体还算稳定。InputCargo()、InputCompartment()、printCargoLoadResult()、printCompartmentStat() 等方法的复杂度为 2。分支数量增加了,不过单个方法没有明显失控。这说明类数量的增加起到了作用。问题更复杂了,方法复杂度没有同步上涨。

不过,这份代码还有几个明显问题。所有类仍然写在同一个 Main.java 中,维护性比较差。LoadDispatcher.sortCargos() 继续使用手写冒泡排序,标准库没有发挥作用。CargoCompartment 中建立了 positions 数组,但这部分数据没有真正进入装载决策。这说明模型中已经出现了“写出来但没有实际参与业务”的部分。第二次作业的结构比第一次成熟,不过抽象还是不够稳,部分设计带有临时拼接的痕迹。

3. 第三次作业:配载平衡与安全评估

第三次作业的业务特征最强。程序不再只判断装载是否超限。程序进入配载平衡计算。代码中除了前后货舱和货物,还引入了 Passenger、Luggage、WeightBalanceCalculator 等类。程序需要去计算总重量、总力矩、实际重心以及重心百分比,最后给出安全性评价。

这次作业最重要的改动,是把计算逻辑集中到 WeightBalanceCalculator 中。calculateTotalWeight()、calculateTotalMoment()、calculateActualCG()、calculateCGPercentage() 这类方法,如果散落在 Main 或 output 中,主流程会很快失去可读性。独立计算类建立之后,主流程仍能保持“输入、建模、计算、输出”的结构。这个变化说明,当业务规则继续增加时,规则本身也需要独立承载。

代码规模如下:

代码规模

类图如下:

PTA3类图

复杂度分析如下:

类复杂度

从复杂度结果来看,第三次作业里复杂度较高的方法主要集中在 CargoCompartment.CargoCompartment()、CargoCompartment.getCurrentWeight()、Flight.getTotalCargoWeightAtCompartment()、InputValidator.inputInt() 等位置。再看 WeightBalanceCalculator 里的核心计算方法,本身并不复杂。公式部分压力较小。输入检查、字符串标识判断以及容器遍历这一类外围流程更复杂。

第三次作业的局限也比较清楚。前后货舱仍然依赖字符串来区分,缺少稳定的类型表达。输入校验失败后直接执行 System.exit(0),处理方式虽然简单,但不利于测试以及错误定位。整体来看,这份代码已经具备较明确的对象划分。它距离稳定、可维护的小型程序还有差距。

三、问题分析与经验总结

这批代码完成时间较早,很多提交时的细节已经记不清。结合当前源代码回看,当时最可能出现的问题不在语法层面。问题主要集中在业务以及设计方面。

第一类问题是输入流程。第一次作业混用了 nextLine() 和 nextDouble()。如果换行处理不好,就容易出现读空行或者货物名称被跳过的情况。这类问题在简单样例中不一定出现,不过评测数据一旦更复杂,就可能导致整体读入错位。

第二类问题是遗留调试语句。第二次作业的 main 方法开头出现了 System.exit(1)。这很像开发过程留下的临时语句。提交前如果忘记删除,程序会在业务逻辑执行前直接结束。这个问题不属于语法错误,不过影响很大。

第三类问题是排序和装载顺序。第二次作业已经按重量降序排序,并且在同重情况下按输入顺序处理。即便如此,只要边界条件没有处理完整,结果仍可能出错。比如目标货舱不存在、同重货物顺序不稳定、局部装得下但整机总载重超限,这些情况都可能让输出与题目要求不一致。

第四类问题是边界值判断。第三次作业涉及重心百分比的安全区间。区间如果写错,或者浮点比较处理得不严谨,就会误判临界数据。类似问题也会出现在最大载重、旅客数、货物数等约束上。边界条件常常决定最终得分。

第五类问题是输出格式。PTA 题目对格式要求严格。第三次作业的输出已经包括标题、分区、数值、小数位以及安全提示。数字格式、空格、换行、提示语顺序只要有细小偏差,就可能在逻辑正确的情况下失分。对于这类题目,输出格式本身就是规则的一部分。

这些问题有一个共同点。实现本身通常不难。提交前的针对性验证反而容易缺少。程序看起来越简单,就越容易忽略边界测试、异常输入测试以及格式核对。最后失分,往往就出在这些地方。

四、改进建议

如果重新实现这一组三次作业,改进方向大致有以下几项。

第一,类应拆分到独立文件中,再按“实体类、服务类、输入输出类、工具类”来组织目录。三个作业都把大量类堆在一个 Main.java 中,提交虽然方便,但阅读、修改以及复用都会受到影响。

第二,应减少对原始字符串以及数组下标的直接依赖。第三次作业中的前后货舱可以定义成枚举类型。第二次和第三次作业中的货物集合也可以改为 List,去替代手动维护容量和下标的数组。这样写会更清楚,也会更稳。

第三,业务规则还应继续从流程代码中抽离。第二次作业的装载策略可以独立成策略类。第三次作业的安全判定以及重心计算也可以继续细分。必要时还可以引入专门的报表对象,用来承接输出数据。这样做的目的在于把后续修改范围缩小。

第四,测试方式需要升级。只靠手工输入几组数据还不够,至少应覆盖正常情况、边界情况、非法输入、容量临界值、重心临界值以及输出格式核对。第三次作业如果缺少针对临界重心数据的测试样例,程序在安全边界上的表现就很难确认。

五、总结

这三次作业把面向对象设计中的几个问题逐步展开了。第一次作业去处理基础建模。第二次作业突出职责分离。第三次作业把重点推进到更复杂的业务约束表达。随着业务规则增加,程序质量的关键已经超出公式是否正确。代码能不能稳定表达这些公式背后的约束关系,同样重要。

从实现过程来看,代码结构确实在发生变化。不同职责开始分配给不同对象。对过程式写法的依赖减弱了。程序也开始从“题目要求”继续抽象出“业务模型”,比如把货物、货舱、旅客、行李、航班以及配载计算器分别视为独立角色。问题也同样存在。封装还不彻底。文件组织还比较粗。异常处理偏简单。部分实现为了尽快完成功能,牺牲了可维护性。

这一阶段更重要的收获,不在某个语法点本身。重点在对“代码结构和问题规模之间关系”的理解。简单题目依靠局部逻辑堆叠也能完成。需求一旦持续迭代,代码组织能力就会立刻接受检验。后续还需要继续加强类设计、输入输出处理、测试方法以及业务抽象能力。

课程和作业的组织方式本身也是有效的。围绕同一主题逐次增加约束,比互不相关的小题更能反映程序设计能力的变化,也更容易暴露早期设计决策对后续迭代的影响。后续讲评如果能增加对优秀作业中类划分、测试思路以及重构思路的展示,教学效果会更好。

posted @ 2026-05-14 22:04  钓只派蒙吃  阅读(14)  评论(0)    收藏  举报