航班装载与配平系统三次迭代作业总结——25201310-甘景凯

航班装载与配平系统三次迭代作业总结

本阶段三次作业都以航班装载为背景。每次作业关注的问题不同。第一次作业完成货物信息输入、排序和总重量统计。第二次作业加入多货舱、舱位容量和装载约束。第三次作业继续加入旅客、行李、力臂、总力矩、重心和 MAC 百分比计算。三次作业不是三个独立题目,而是同一系统的三次扩展。

从代码规模看,变化较清楚。第一次作业有 133 行代码,5 个类。第二次作业有 290 行代码,7 个类。第三次作业有 434 行代码,11 个类。业务对象增加后,程序不再只是输入和输出。它需要多个类共同完成业务处理。这个过程让我开始理解类设计和需求变化之间的关系。

从知识点看,三次作业涉及数组、集合、排序算法、对象封装、聚合关系、输入校验、约束判断和计算模块抽取。难点主要在建模,分析类与类之间的关系以及正确的使用。到第三次作业时,如果仍把主要逻辑写在主函数中,代码会变得难以阅读,也不便修改,所以增加control类,计算类就显得格外重要。

这三次作业的意义不只在于完成程序。它也体现了思路的变化。第一次作业关注“怎样算出结果”。第二次作业开始关注“功能应该由哪个类负责”。第三次作业进一步暴露出一个问题:原有结构能否支持新的约束。

一、前言

三次作业围绕同一业务背景展开。第一次作业处理基础货物装载统计。第二次作业加入多货舱和装载约束。第三次作业加入旅客、行李、重心和配平计算。这个过程说明,重点在于考察我们对面向对象编程的结构的理解熟悉度,还包括在需求增加时调整程序结构。

从难度变化看,三次作业不是单纯增加输入规模,而是每次都添加新的逻辑。每次作业都加入新的业务规则。第一次作业只需要排序和总重判断。第二次作业需要考虑货舱划分、目标舱位和装载状态。第三次作业需要根据重量和力臂计算飞机重心。每增加一个约束,原有结构都可能需要调整。

因此,回顾这三次作业时,不能只看程序能否运行。还要看类划分是否合理,职责分配是否清楚,边界情况是否覆盖,代码是否便于继续扩展。下文围绕这些方面进行分析。

二、设计与分析

1. 第一次作业分析:基础装载清单的建立

第一次作业目标明确。程序读取航班编号、最大载重和货物信息。随后按重量降序排序,输出装载清单,并判断总重量是否超过限制。这个版本规模较小,但已经有基本的面向对象结构。程序包含 Flight、Cargo、CargoSorter、Loadmanifest 和 Print 五个类。

Flight 保存航班编号、最大载重和货物数量。Cargo 表示单个货物。Loadmanifest 组合航班和货物集合,并统计总重量。CargoSorter 负责排序。Print 负责输出。这些类之间各自有职责划分,实现自己相对应的功能。

第一次作业把排序操作放入 CargoSorter 类,而不是直接写在主函数里。CargoSorter.sort() 使用冒泡排序,按货物重量从大到小排列。主流程因此比较清楚:输入数据,构造对象,排序,生成清单,输出结果。对于第一次作业,这种逻辑可以满足需求。

但是这个版本也有不足之处。第一,货物容器使用数组。当前规模下可用,但扩展性有限。第二,冒泡算法是手写,可以完成任务,但不如标准库排序便于复用和维护。第三,输入校验较少,异常输入处理不足,如果增加异常输出则程序很可能会报错崩溃。第四,一些写法是面向过程编写,代码可维护性些许不足。

总体看,第一次作业完成了基本功能,也为后续版本提供了起点。它的优点是结构简单,容易理解。不足集中在扩展性和健壮性上。

图1-1 第一次作业类图

图1-2 第一次作业代码行统计

图1-3 第一次作业方法复杂度统计

2. 第二次作业分析:多货舱装载模型的扩展

第二次作业在第一次作业基础上扩展。程序不再只处理航班和货物,还加入货舱和舱位。新增的主要类有 CargoCompartment、Position、LoadDispatcher 和 InputValidator。程序的业务模型比第一版完整。

这一版中,Flight 通过 List<CargoCompartment> 管理多个货舱,并提供 findCompartmentByID() 定位目标货舱。CargoCompartment 是核心类。它管理货舱编号、最大载重、位置集合、已装货物和已使用位置数。需求从简单统计计算转向装逻辑的表达和约束实现。

程序主流程也更清楚。先读取航班数据,再读取货舱数据,然后读取货物数据。之后按重量降序排序,最后根据货物目标舱位执行装载。LoadDispatcher.sortCargos() 是先统一排序,再分配货物思路。这比第一版更接近业务逻辑。

集合框架的使用也增加了。货舱列表和货物列表都改成 List。与数组相比,List 更适合后续增删和扩展。

第二次作业也暴露出问题。典型问题出现在 CargoCompartment。类中已有 usedPositionCount 和 positions,说明设计时考虑了舱位容量。但在 addCargo() 方法中,程序只判断重量,没有根据 positions.size() 限制可装货物数量。也就是说,字段被定义了,但没有完整进入业务规则。

InputValidator 的作用也有限。它只返回布尔值,没有形成统一的错误处理流程。输入越界或格式错误时,程序缺少明确反馈,错误反馈不足不清晰。另外,Print.printResult() 同时负责结果组织和状态说明。输出层与部分业务逻辑存在耦合。

总体看,第二次作业是结构扩展的关键一步。第一版主要完成单一功能。第二版开始形成可以继续扩展的程序骨架。第三次作业能够加入配平计算,也依赖这一版的结构基础。

图2-1 第二次作业类图

图2-2 第二次作业代码行统计

图2-3 第二次作业方法复杂度统计

3. 第三次作业分析:从装载管理到重量配平计算

第三次作业继续扩展前两次内容,也是结构最复杂的一版。它新增了 Passenger、Luggage、Input 和 WeightBalanceCalculator 等类。程序不仅处理货舱和货物装载,还要处理旅客重量、行李重量、力臂、总力矩、重心和 MAC 百分比。程序目标从输出装载结果,转向判断整体装载是否满足飞行安全要求。

这一版的核心类是 WeightBalanceCalculator。它集中定义空机重量、空机力臂、旅客力臂、前后货舱力臂、MAC 长度和重心允许范围等常量。calculate() 方法负责计算总重量、总力矩、重心位置和 MAC 百分比。与前两版相比,这里已经形成独立的计算模块。公式和参数集中放置,便于阅读和修改。

Input 类的引入也改善了主流程。主函数不再直接写大量 Scanner 读取语句,而是通过 Input.getFlightId()、Input.getPassengers() 和 Input.loadCargos() 等方法完成输入。这样主函数更短,输入模块和业务模块的边界也更清楚。

从装载规则看,第三次作业修正了第二次作业中的一个问题。在 CargoCompartment.addCargo() 中,程序先检查 usedPositionCount >= positions.size(),再检查重量是否超限。这样,货舱容量约束才真正进入判定逻辑。前一版只是定义了字段,这一版把约束落实到了方法中。

第三次作业也带来新的问题。第一,Flight 提供了 addPassenger() 方法,也维护了 passengerCount 字段。但主函数实际使用 flight.getList().add(passenger)。第二,WeightBalanceCalculator.calculate() 查找前后货舱时使用双重循环,逻辑重复,可以简化。第三,程序多处使用 System.exit(0) 处理中断。小程序中这种方式容易实现,但不利于测试和扩展。

总体看,第三次作业已经具备小型业务系统的基本形态。类拆分和封装仍有改进空间,但程序已经能围绕多个实体完成协同处理,并输出完整结果。这一版让我认识到,功能完成和结构合理不是同一件事。

图3-1 第三次作业类图

图3-2 第三次作业代码行统计

图3-3 第三次作业方法复杂度统计

三、作业心得

三次作业都可以运行,但编码和复盘中出现了不少问题。第一个问题在建模阶段。我一开始更关注字段是否写全,没有检查字段是否真正参与约束判断。第二次作业中的 usedPositionCount 就是例子。当时我已经考虑到货舱容量不仅和重量有关,也和位置数有关,所以设计了位置集合和已使用位置数。但在 addCargo() 中,这个字段没有用于限制装载数量。这个问题说明,字段设计不等于规则实现。

第二个问题是封装不足。第三次作业中,Flight 类已经提供 addPassenger() 方法,理论上应由它统一维护乘客集合和人数统计。但主函数中直接使用 getList().add(passenger)。程序可以运行,但 passengerCount 会与实际数据不一致。由此可以看出,封装不是为了形式整齐,而是为了保证对象内部状态一致。

第三个问题是错误处理过于简单。第三次作业中,我多次使用 System.exit(0)。输入越界时退出,货舱容量不足时也退出。这种写法实现快,但不利于测试,也不便于后续扩展。如果以后要支持重新输入、异常恢复或图形界面,这种方式不合适使用。

最后一个体会与测试有关。最开始,我主要用正常样例测试程序能否输出结果。后来发现,边界测试和异常测试更容易暴露问题。例如货物数量为 0、货舱重量刚好达到上限、位置已满但重量未超限、重心接近边界。这些情况更能检查程序是否完整。很多问题不是因为功能不会写,而是因为前期没有考虑边界情况,所以以后要增加思考的时间,考虑周全,减少边界情况通不过测试的情形 。

四、改进建议

结合三次作业的实现情况,后续可以从以下方面改进。

第一,将多个类拆分到独立的 .java 文件中。三个版本都采用单文件多类写法。当前规模下还能使用,但类数量增加后,查找和维护会变慢。将 Flight、Cargo、CargoCompartment、Passenger 和 WeightBalanceCalculator 等核心类拆开,更符合 Java 项目的组织方式。

第二,进一步抽象装载策略。当前装载逻辑主要是“先按重量降序排序,再放入指定货舱”。如果后续要求优先保证重心平衡,或自动寻找更合适的舱位,现有代码需要较大修改。可以引入装载策略类或接口,把“如何分配货物”和“货物、货舱的数据定义”分开。

第三,统一输入校验和错误处理机制。第二次作业中,校验函数返回布尔值。第三次作业中,多处直接退出程序。这两种方式不统一,也不便维护。后续可以使用异常处理,也可以改为循环重输机制。

第四,加强封装,减少外部对内部集合的直接访问。第三次作业中的乘客列表应统一通过 addPassenger() 方法维护。如果需要读取数据,可以提供统计方法或只读视图,而不是直接暴露可变集合。

第五,继续分离输出模块和计算模块。当前打印类承担了较多格式组织任务。后续如果要支持文件输出、图形界面或网页展示,应让计算模块先返回结果对象,再由不同展示层完成输出。

第六,补充系统测试。第三次作业涉及重量和重心计算,测试不能只看程序是否有输出,还要验证结果是否在合理范围内。可以建立测试数据表,分别列出空载、满载、前舱偏重、后舱偏重和重心临界值等情况,用数据检查程序行为。

五、总结

通过这三次作业,我对面向对象程序设计有了更具体的认识。最初我更关注尽快写出结果。三次迭代之后,我开始意识到,功能正确只是基础。类划分、职责边界、约束完整性和可扩展性同样重要。第三次作业加入旅客、行李和重心计算后,这一点更明显。设计质量会影响实现效率,也会影响后续维护。

从收获看,主要有四点。第一,我对对象建模的理解更清楚。通过 Flight、CargoCompartment、Passenger 和 WeightBalanceCalculator 等类,我开始区分实体类、控制类和计算类的职责。第二,我对集合和数据组织方式有了直接认识。第三,我对约束建模有了更深入的理解,开始尝试分开处理输入、装载、计算和输出。第四,我的测试意识有所加强,认识到程序质量不能只靠正常样例判断。

同时,我也看到自己的不足。异常处理机制还不成熟。类之间耦合仍然偏高。部分方法粒度较粗。对于重构、单元测试和规范工程组织,我目前还只是初步接触。第三次作业虽然基本实现功能,但仍有封装不足、重复遍历和错误处理简单等问题。这些问题说明,后续需要提高的不只是编码速度,还包括分析、设计和维护代码的能力。

对于课程安排,我认为递进式作业设计非常有价值。它让我在同一主题下修改已有程序,而不是每次都从零开始。通过增加类设计、测试样例和重构思路分析,让我们加深了面向对象编程的理解。相比只给出最终答案,说明“为什么这样建模”和“这一版相对上一版改进了什么”,更有助于形成稳定的设计思路。总体来说,这三次作业锻炼了我的 Java 编码能力,也让我开始建立从需求分析、结构设计、编码实现到测试改进的完整认识。

posted @ 2026-05-17 10:05  fish77  阅读(9)  评论(0)    收藏  举报