面向对象程序设计——第一次总结
一、前言
随着第三次PTA作业的截止,我渐渐学会了一些简单的Java知识。从第一题的简单框架逐渐加难度,在原本的基础之上新增更多功能,让我渐渐熟悉了Java的编程知识:
1.类与对象:基本类的设计(航班、货物);
2.单一职责原则(SRP):每个类只负责一个功能
3.类间关系:组合(货舱与位置)、聚合(货舱与货物);
4.异常处理:输入为负数或超过范围时立即停止程序并提示;
从第一题到第三题,输入数据逐步增多,每题要求实现的类也不断增多,类里的方法也从2~3个/类到3~6个/类,题量逐步加大,难度渐渐上升。让人抓耳挠腮的同时也提高了我的编程能力。
二、设计与分析
(1)第一次作业
作业要求
设计一个基础的航班货运配载模块。系统需要记录航班的基本信息(航班号、最大起飞重量、最大业载重量)。地勤人员可以按照货物重量从高到低向该航班添加货物(货物名称、重量)。系统需要实时计算当前已装载的总重量,并判断是否超载。
实现方式
先读取输入数据,再用“货物列表”贮存输入的货物信息,再按照货物重量从高到低对列表进行排序,再创建一个“航班”对象,记录航班号和最大载重,依次将排序后的货物添加进航班,并计算当前重量,再按要求输出。
复杂度分析


PTA 01复杂度如上图。
1.Cargo类:无维护风险
2.CargoSort类:最大嵌套深度5,代码可读性差,说明排序算法应该优化
3.Flight类:无维护风险
4.LoadManifest类:无维护风险
5.Main类:无维护风险
(2)第二次作业
作业要求
航班信息管理:记录航班号、最大起飞重量、最大业载重量。 货舱管理: 每个货舱有唯一标识(如“前舱”)、最大载重、行数、列数(组成位置网格)。 货舱与其位置是组合关系(CargoCompartment 创建时内部生成 Position 列表)。 货舱与装载的货物是聚合关系(Cargo 可独立存在)。 货物装载: 输入所有待装载货物(名称、重量、目标货舱ID)。 系统先按货物重量从高到低排序,再依次尝试将货物装入指定的货舱。 如果目标货舱的当前重量 + 该货物重量 ≤ 该货舱最大载重,则装载成功,否则装载失败并给出提示。 输出要求: 按排序后的顺序输出每件货物的装载结果(成功或失败)。 输出每个货舱的已装载总重量及状态(是否超载)。 输出航班整体总重量及与最大起飞重量、最大业载重量的对比,判断整体是否超载。
实现方式
按要求读取所给数据,Position类储存货舱行列,Cargo存储货物名称、重量,CargoCompartment储存货舱ID、最大载重、位置列表(组合关系)、已装货物列表(聚合关系),Flight储存航班信息 、货舱列表、 旅客列表,LoadDispatcher负责对货物按重量降序排序,InputValidator提供静态方法校验整数和浮点数范围,使用 LoadDispatcher 对所有货物按重量降序排序,遍历排序后的货物列表,根据货物的“目标货舱ID”找到对应的货舱对象,判断货舱当前重量 + 货物重量 ≤ 货舱最大载重,记录每条货物的装载结果,先输出排序后的装载结果,遍历每个货舱,输出已装重量、最大载重、状态,累加所有货舱重量得到航班总重量,与最大起飞重量、最大业载重量比较,输出整体状态。
复杂度分析


PTA 02复杂度如上图。
1.LoadDispatcher类:最大嵌套深度大于4,代码可读性差,说明排序算法不够好,后续优化应该改一改排序算法
2.Main类:语句数偏多,可以更简单
(3)第三次作业
作业要求
航班信息管理:记录航班号、最大起飞重量、最大业载重量。 货舱管理: 每个货舱有唯一标识(如“前舱”)、最大载重、行数、列数(组成位置网格)。 货舱与其位置是组合关系(CargoCompartment 创建时内部生成 Position 列表)。 货舱与装载的货物是聚合关系(Cargo 可独立存在)。 货物装载: 输入所有待装载货物(名称、重量、目标货舱ID)。 系统先按货物重量从高到低排序,再依次尝试将货物装入指定的货舱。 如果目标货舱的当前重量 + 该货物重量 ≤ 该货舱最大载重,则装载成功,否则装载失败并给出提示。
实现方式
按要求输入,数据校验中,任何输入的数值为负数 → 输出“数值不能为负数!”→ 程序停止,任何数值超过合理范围→ 输出“输入必须在 X 到 Y 之间!”→ 停止,前舱货物总重量超过前舱最大载重 → 输出警告 → 停止,后舱货物总重量超过后舱最大载重 → 输出警告 → 停止,在新增类里,Passenger 类储存行李重量。旅客总重 = 75kg+ 行李重量,Luggage 类只记录行李重量,在 Passenger 构造器内创建(组合关系),WeightBalanceCalculator 类是纯静态方法,输入 Flight 对象,输出计算结果。不存储任何数据。旅客总重 = Σ (75 + 行李重量),旅客力矩 = 旅客总重 × 18.0(旅客舱力臂),前货舱力矩 = 前舱货物总重 × 12.0,后货舱力矩 = 后舱货物总重 × 22.0,空机力矩 = 40000 × 16.25,全机总重 = 40000 + 旅客总重 + 前舱总重 + 后舱总重,全机总力矩 = 空机力矩 + 旅客力矩 + 前舱力矩 + 后舱力矩,实际重心 = 全机总力矩 / 全机总重,重心百分比 = ( (实际重心 - 15.0) / 5.0 ) × 100,按题目给定的“载重平衡舱单”格式输出,所有重量、力矩、重心保留一位小数,前舱和后舱的货物列表需要逐行输出(货物编号 + 重量),最后根据 CG% 是否在 25.0~38.0 之间输出“安全(GREEN)”或“危险(RED)”。
复杂度分析


1.Main类:main方法里,写了110行,语句74条,复杂度22,说明业务逻辑全部写进了main方法里,业务流程全在main里,导致Main的失控,应该把main拆成6~8个小方法,让代码更方便维护
2.WeightBalanceCalculator类:同Main类,一个方法太长了,需要拆分成一个个小方法
三、踩坑心得
1.Scanner输入换行问题,读取字符串时读到了空串,导致结果不一致,总是显示“输入数据不能为负数!”或没有输入,改进方法是在nextInt()后加input.nextLine()吃掉回车,操作以后输出就正常了;
2.题目集01里的测试点“未装载货物测试”一直显示“非零返回”是为什么?引用出错了吗?加了if判断还是报错。我再想想吧。
3.题目集02里的测试点“case1”“case4”没过去是为什么?测试点太模糊了,我有点无从下手。我再问问过了的同学吧。
4.题目集03里的测试点“前舱容量不足测试”“后舱容量不足测试”“输入数据范围非法(装载前舱货物数量)测试”总是答案错误,我先怀疑是因为格式没对上样例,结果真有一部分没对上,但改了以后重新提交还是没过。后来询问同学改进代码里的参数,反而呢从70到40了,我不知道是不是格式没对上还是别的什么,容量不足测试结果就是不理想,还是后期在总题目集里优化一下吧。至于输入数据范围非法,就更是摸不着头脑了,但是我会找过了这个测试点的同学请教的。
四、改进建议
针对第三次作业中暴露出的代码结构问题,我提出以下可持续改进方案。
首先,我要将 main 方法拆分为 6 到 8 个小方法,包括 readFlightInfo() 读取航班基础信息、readCargoCompartmentInfo() 读取货舱信息、readPassengerAndLuggage() 读取旅客和行李、readCargoList() 读取货物列表、validateAllInputs() 统一校验、executeLoading() 执行装载、calculateAndPrintBalance() 计算重心并输出、printCargoDetails() 输出货舱货物明细,每个方法控制在 20 行以内,以降低复杂度和提升可维护性。
其次,我要重构 WeightBalanceCalculator 类,将其拆分为多个静态方法:calculateTotalPassengerWeightAndMoment()、calculateCargoMoment()、calculateAircraftTotalWeightAndMoment()、calculateCGPct()、getSafetyStatus(),每个方法只负责一项计算,便于单独测试和复用。
针对容量不足测试点不过的问题,我觉得需要检查装载顺序是否严格按照货物重量从高到低排序后依次尝试,并确认边界条件使用的是 ≤ 而非 <。
针对数据范围非法测试点不过的问题,应注意第三次作业中新增的前舱货物数量范围校验,校验时机应放在读取完所有货物信息之后、开始装载之前统一进行,校验失败后直接输出提示并终止程序,不再执行后续计算和输出。
最后,建立可持续改进机制:将 PTA 未通过的测试点输入保存为本地文件,建立个人踩坑文档,记录每个测试点的特征、错误原因和解决方案,便于下次遇到同类问题时快速定位。我希望通过这些措施,可以系统性地提升我的代码质量、测试覆盖率和问题排查效率。
五、总结
针对本次三次作业中出现的问题,我提出以下几点改进建议:
1. 减少 Main 方法的代码量
第三次作业中,Main 方法的代码行数达到了 110 行,语句 74 条,复杂度高达 22。这说明我把太多业务逻辑塞进了主方法,导致代码可读性差、调试困难、维护成本高。建议将输入解析、数据校验、货物装载、重量计算、输出格式等不同职责拆分到独立的小方法中,每个方法只做一件事,这样既符合单一职责原则,也便于单元测试,写健康的代码。
2. 优化排序算法
从复杂度分析可以看出,LoadDispatcher 类的最大嵌套深度大于 4,代码可读性较差。目前我使用的是手动实现的排序算法,如果后期能用 Java 自带的collection.sort() 或 Arrays.sort() 实现按重量降序排列就好了,这样不仅能减少嵌套深度,还能降低出错概率。
3. 完善异常处理与数据校验
第三次作业中,“前舱容量不足测试”“后舱容量不足测试”“输入数据范围非法测试”始终无法通过。我怀疑校验逻辑和输出格式与题目要求存在细微差异。建议多给一点参考样例输出,逐字符比对格式(空格、换行、小数点位数等)。
4. 清晰给出单元测试
目前我只能通过 PTA 的测试点来验证代码,如果测试点不明确,我将对错误的代码无从下手。所以建议题目给出清晰明了的测试点。
通过这三次 PTA 作业,我从最初只会写一个简单的航班配载模块,逐步掌握了类与对象、类间关系(组合与聚合)、单一职责原则、异常处理、数据校验、排序算法、复杂度分析等 Java 编程的核心知识。
三次作业的难度逐次递增:第一次只需要管理一个航班和一批货物;第二次引入了货舱、位置网格、装载失败提示;第三次增加了旅客重量、力矩计算、重心百分比判定,并要按严格的“载重平衡舱单”格式输出。每一次迭代都在原有代码基础上增加新功能,这让我在苦思冥想中深刻体会到了“增量开发”和“代码可扩展性”的重要性,以及我在设计思路上的不足之处。
同时,我也暴露了不少问题:Main 方法过于臃肿、排序算法效率低、部分测试点反复不过、踩坑后没有系统记录等。这些问题将成为我下一阶段改进的重点。
在今后的学习中,我会更加注重代码的模块化设计,遵循面向对象的设计原则,多写可复用的方法,多进行本地测试,并主动向通过测试的同学请教思路。我相信,每一次踩坑都是进步的机会,每一行代码都是经验的积累。

浙公网安备 33010602011771号