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

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

作者:周昊洋

一、前言

从开学到现在,我一点点完成了航空器配载与货运管理系统的三次迭代作业,这可是我大一第一次正经接触Java面向对象编程的完整项目,说真的,一开始还挺手足无措的。三次作业不是孤立的,而是一步步升级的,难度慢慢增加,知识点也从最基础的类和对象,慢慢过渡到多个类一起协作、遵守单一职责原则,到最后还要结合航空专业的物理计算逻辑,每一步都得慢慢琢磨,对我来说,确实是一次实打实的编程入门实践。

我先简单说说三次作业的核心情况,都是我自己实际做下来的真实感受:

  1. 作业1(基础配载):就一道题,难度不算特别大,但对我来说已经有点挑战了。核心要学的就是Java类的定义、封装,还有数组、选择排序,以及控制台的输入输出,最后还要判断货物是否超载。最关键的是要遵守单一职责原则,得把货物、航班、计算、排序这些功能,拆分成一个个独立的类,不能混在一起。这也是我第一次严格按照这个原则写代码,以前总习惯把所有逻辑都堆在主函数里,这次拆分完,才发现代码清楚多了。

  2. 作业2(多货舱管理):还是一道题,但难度比第一次高了不少。在第一次作业的基础上,新增了多货舱管理,还有货舱的位置、货物调度、输入校验和格式化输出。要学的东西也多了,比如类的组合和聚合关系,怎么让多个类互相调用,还有冒泡排序、复杂的条件判断,以及怎么规范输出格式。这次类的数量一下子变多了,一开始我都搞不清哪个类该调用哪个类,折腾了好久才理顺逻辑。

  3. 作业3(配平计算):这是三次作业里最难的一道,当时我卡了好几天才做完。新增了旅客和行李的管理,最核心的是要实现航空器载重平衡的物理计算,比如力矩、重心、MAC百分比这些,还要判断配平是否安全。不仅要学输入合法性校验、组合类的设计,还要把数学公式转换成代码,对我这个刚学Java的大一新生来说,确实有点吃力。

三次作业加起来就3道题,但每一道都比上一道难,从简单的单货舱装载,到多货舱的精细化管理,再到专业的配平安全计算,一步步贴近真实的航空货运业务。通过这三次练习,我从只会写简单的Java语法,慢慢学会了怎么用面向对象的思想设计代码,也终于明白,代码规范和类的职责划分,真的太重要了。虽然过程中遇到了无数个bug,有时候调试到深夜都没解决,但每解决一个问题,我对Java编程的理解就更深一点,那种成就感还是挺足的。

二、设计与分析

这部分我就结合自己写的代码、类的结构,还有实际实现的功能来分析,全程都是我自己的真实设计思路,严格遵守作业要求的单一职责原则,每个类只做一件事,不搞冗余。

(一)作业1:基础航班货运配载模块 设计分析

作业1的核心需求很简单:录入航班的基本信息,按照货物重量从高到低的顺序装载货物,计算所有货物的总重量,最后判断是否超载。

当时我按照单一职责原则,设计了5个独立的类,每个类的职责都很明确:

  1. Cargo类:就负责存储货物的名称和重量,提供get和set方法,只做数据封装,不处理任何计算、排序的逻辑,也不参与输出。一开始我还想在这个类里加个打印货物信息的方法,后来想起老师说的单一职责,就赶紧删掉了,只保留了最基础的数据存储功能。

  2. Flight类:专门存储航班的信息,比如航班号、最大载重,也是纯数据类,只负责存数据、供其他类调用,不做任何业务逻辑处理。

  3. CargoSorter类:唯一的功能就是给货物排序,用选择排序实现重量从高到低的排序,别的什么都不做。当时我写这个类的时候,还写错了排序逻辑,折腾了快一个小时才改对。

  4. LoadManifest类:纯计算工具类,就一个方法,就是计算所有货物的总重量,输入货物数组,输出总重量,不涉及任何其他功能。

  5. Main类:主程序类,负责统筹所有事情,比如从控制台接收输入,调用CargoSorter排序,调用LoadManifest计算总重量,最后输出结果。所有的逻辑调用都在这里, 但 不做具体的计算和排序。

设计心得:这是我第一次真正理解单一职责原则的好处。一开始我图省事,把排序、计算都写在Main类里,结果代码乱得一塌糊涂,后来按照要求拆分之后,代码一下子就清晰了。比如我想修改排序逻辑,只需要改CargoSorter类,不会影响到计算和输入输出;想修改货物的属性,只改Cargo类就行,不用动其他类。我用SourceMonitor查看了代码报表,每个类的方法数都很少,复杂度也很低,完全符合基础作业的设计要求。

类图说明:我用PowerDesigner画了简单的类图,Cargo和Flight是独立的数据类,CargoSorter和LoadManifest是工具类,Main类负责调用所有类,彼此之间没有多余的关联,职责划分得很清楚。
(二)作业2:多货舱管理与重量排序装载 设计分析

作业2是在作业1的基础上迭代升级的,核心需求比第一次复杂多了:要管理多个货舱,每个货舱有自己的最大载重和位置,货物要按目标货舱装载,还要判断每个货舱和整个航班是否超载,最后还要按规范格式输出结果。

这次我新增了好几个类,总类数达到了9个,每个类的职责划分得更细致了:

  1. Position类:就负责存储货舱的行列位置,比如第几行第几列,提供一个获取位置名称的方法,只做位置相关的数据管理,别的什么都不做。

  2. CargoCompartment类:货舱的核心类,负责管理货舱的ID、最大载重、位置列表,还有装载的货物,还能判断货舱是否超载。这个类里有一个addCargo方法,专门用来装载货物,判断当前重量加货物重量是否超过最大载重。

  3. LoadDispatcher类:调度类,就两个功能,一是给货物按重量降序排序,二是根据货物的目标货舱ID,找到对应的货舱。当时写这个类的时候,排序逻辑还出了点问题,同等重量的货物没有按输入顺序排列,后来加了判断条件才解决。

  4. InputValidator类:输入校验类,专门判断输入的数字是否合法,比如货舱数量、货物重量是不是正数,不符合要求就提示错误,不参与任何业务逻辑和输出。

  5. OutputFormatter类:输出格式化类,所有的打印输出都由这个类负责,比如装载结果、货舱状态、航班状态,统一格式,这样Main类里就不用写一堆printf语句,看起来更整洁。

设计心得:这次作业让我真正理解了类的组合和聚合关系。组合关系就是“不可分割”,比如货舱和位置,货舱创建的时候,位置就跟着创建了,货舱不存在了,位置也没用了;聚合关系就是“可以独立存在”,比如货舱和货物,货物可以单独存在,不一定非要装在某个货舱里。所有类都严格遵守单一职责,校验输入的类不负责输出,排序的类不负责计算,输出的类不负责处理逻辑,这样后期测试的时候,定位bug特别快,比如输出格式错了,只需要改OutputFormatter类就行。

(三)作业3:航空器配载与货运管理系统-配平计算 设计分析

作业3是三次作业的最终迭代,难度也是最大的,核心需求是新增旅客和行李的管理,还要实现航空器载重平衡的物理公式计算,最后判断配平是否安全。作业要求新增4个类,系统总类数达到10个左右,还禁止使用继承和多态,只能用基础的类协作完成。

我新增的4个类,还有优化的类,职责划分都很细:

  1. Luggage类:就一个功能,存储行李的重量,提供get和set方法,是旅客的组合部分,不能独立存在。

  2. Passenger类:负责管理旅客,计算旅客的总重量,也就是标准体重75kg加上行李重量。这个类和Luggage是组合关系,在Passenger的构造方法里,会创建Luggage对象,不能在外部修改行李重量,完全符合作业要求。

  3. WeightBalanceCalculator类:纯计算工具类,也是这次作业的核心类,所有的物理公式计算都在这里,比如旅客总力矩、货舱总力矩、全机总重量、重心、MAC百分比,还有安全判断。这个类没有任何成员变量,所有计算都靠接收参数完成,调用的时候只需要传入对应的数组和数值,就能得到结果,特别规范。

  4. 优化后的InputValidator类:之前的InputValidator类功能比较简单,这次我完善了它,统一处理所有非法输入,比如输入负数、超出范围的数值,只要检测到,就立即打印提示,然后停止程序运行,不用再在Main类里反复写校验逻辑。

设计心得:这次作业真的让我成长了很多,禁止使用继承和多态,让我学会了用基础的类协作完成复杂功能。最让我头疼的就是WeightBalanceCalculator类,里面的公式特别多,比如重心百分比的计算,我反复核对了好几遍,生怕算错一个数,导致整个配平判断错误。还有旅客和行李的组合关系,一开始我没搞懂,怎么都不能在Passenger构造方法里创建Luggage对象,折腾了大半天。这次设计也让我明白,好的代码设计,不是代码越多越好,而是职责越清晰越好,每个类只做一件事,代码才会更易维护、更易调试。

三、采坑心得

这部分我就实打实说自己三次作业中遇到的问题,每个问题都有具体的测试数据、代码逻辑,还有我当时的解决过程,都是我自己一点点踩坑、填坑的真实经历。

(一)作业1 踩坑记录

  1. 控制台输入回车坑(最致命,卡了我两个小时)

问题:当时我用nextInt()读取货物件数n之后,直接用nextLine()读取货物名称,结果程序总是跳过货物名称输入,直接报错,我反复调试,都找不到原因,急得不行。

测试:比如我输入航班号CA1201,然后输入最大载重2000.0,再输入货物件数3,按回车之后,程序直接跳过第一个货物名称的输入,直接让我输入货物重量,输入之后就报错。

解决:后来我翻了作业提示,才知道nextInt()读取数字后,会留下一个回车符,nextLine()会直接读取这个回车符,导致无法读取到真正的货物名称。然后我按照提示,在nextInt()之后加了一行scanner.nextLine(),专门吸收这个回车符,问题一下子就解决了。这是我第一次知道Java输入的这个细节,也让我明白,编程真的要细心,一点点小细节出错,程序就会出问题。

  1. 选择排序逻辑错误(低级错误,但很致命)

问题:作业要求货物按重量从高到低装载,我最开始写选择排序的时候,把判断条件写反了,变成了按重量升序排序,测试的时候发现输出顺序和样例完全不一样。

测试:输入3件货物,重量分别是500、850、128,按照作业要求,应该输出850、500、128,但我当时输出的是128、500、850,明显不符合要求。

解决:我逐行对比自己的排序代码,发现判断条件写反了,把b[j].getcargoWeight() < b[max].getcargoWeight()改成了b[j].getcargoWeight() > b[max].getcargoWeight(),修改之后再测试,排序就正确了。这件事也让我明白,写代码的时候,一定要仔细核对逻辑,不能想当然。

  1. 小数输出格式错误(细节问题,扣过分)

问题:作业要求所有输出的数值都保留1位小数,我最开始没有注意,直接用System.out.println()输出,结果小数位数不统一,有的保留了2位,有的保留了3位,提交之后扣了分。

解决:后来我查了资料,学会了用printf("%.1f")格式化输出,把所有需要输出的重量、载重,都用这个格式,严格按照样例修改,最后输出格式就完全符合要求了。

(二)作业2 踩坑记录(难度升级,坑也更隐蔽)

  1. 货舱ID匹配失败(最隐蔽,查了很久才找到)

问题:货物的目标货舱ID输入之后,程序总是找不到对应的货舱,导致装载失败,明明我输入的货舱ID和定义的一样,就是匹配不上。

原因:我当时用了“”来比较货舱ID,也就是两个字符串,我以为“”能比较内容,后来才知道,Java中字符串比较内容,必须用equals()方法,“==”比较的是地址,不是内容,所以即使内容一样,也会匹配失败。

解决:我修改了LoadDispatcher类里的findCompartment方法,把原来的“==”改成了equals(),比如c.getId().equals(targetId),修改之后,货舱ID就能正确匹配,装载也能正常进行了。这个坑让我记住了,Java中字符串比较,一定要用equals()方法。

  1. 冒泡排序同等重量顺序错误(细节问题,容易忽略)

问题:作业要求,同等重量的货物,要按照输入的先后顺序排列,但我最开始写的冒泡排序,只判断了重量,没有判断输入顺序,导致同等重量的货物,输出顺序和输入顺序不一样。

解决:我在排序逻辑中增加了一个判断条件,当两个货物重量相等时,比较它们的输入顺序(我在Cargo类里加了一个order属性,记录输入顺序),重量相同的情况下,输入顺序早的排在前面,这样就符合作业要求了。

  1. 总重量计算错误(逻辑漏洞,导致超载判断错误)

问题:航班总重量计算的时候,我没有累加所有货舱的重量,只算了其中一个货舱,导致航班总重量比实际小,超载判断出现错误,比如实际已经超载了,但程序判断为正常。

解决:我在Flight类里新增了一个getTotalWeight方法,遍历所有货舱,把每个货舱的当前重量累加起来,得到航班总重量,然后逐行测试每个货舱的重量,确保累加正确,修改之后,超载判断就准确了。

(三)作业3 踩坑记录(最难,坑也最复杂)

  1. 输入负数程序未退出(鲁棒性问题,作业要求必须解决)

问题:作业要求,输入非法数据(比如负数),程序要立即停止运行,并提示错误,但我最开始写的InputValidator类,没有处理负数的情况,输入负数之后,程序还会继续运行,不符合鲁棒性要求。

解决:我完善了InputValidator类的validateInt和validateDouble方法,在方法里增加了判断,如果输入的数值小于0,就打印“数值不能为负数!”,然后调用System.exit(0)停止程序,这样输入负数之后,程序就会立即退出,符合作业要求。

  1. 配平计算公式错误

问题:重心百分比(CG% MAC)的计算错误,导致安全判断结果错误,比如样例数据计算出来应该是安全,但我的程序判断为危险,反复核对数据,都找不到原因。

测试:用作业给的样例数据,空机重量40000.0kg,旅客总重605.0kg,前舱货物1000.0kg,后舱货物3700.0kg,按照公式计算,重心百分比应该是33.0%,在安全范围内,但我的程序计算出来是38.5%,判断为危险。

解决:我逐行核对WeightBalanceCalculator类里的计算公式,发现是重心百分比的公式写错了,正确的公式是((实际重心 - 15.0)/5.0)*100,我当时把15.0写成了16.25,导致计算错误。修改公式之后,再用样例数据测试,结果就正确了,安全判断也没问题了。这件事让我明白,做涉及公式的编程题,一定要逐字核对公式,不能凭记忆写。

  1. 货舱容量不足判断错误(逻辑漏洞,容易忽略)

问题:当货物超重,货舱容量不足时,程序没有正确提示“剩余容量不足”,而是继续装载,导致输出结果错误,且如果前舱后舱剩余容量都不足时要将两个货舱都不足的输出结果都写出来而不是只输出一个之后便退出。

解决:我在Main类里,实时累加货舱的当前重量,每装载一件货物,就判断当前重量加货物重量是否超过货舱最大载重,如果超过,就标记,然后最后统一统计到底哪个货舱超重并给出相应输出,这样就能正确判断货舱容量不足的情况了。

整体心得:三次作业的坑,从最基础的输入语法错误,到类的调用逻辑错误,再到专业的公式计算错误,一步步升级。我也慢慢学会了调试代码的方法,比如逐行输出变量值,查看哪里出错;用测试数据一点点验证,排除错误;先写注释再写代码,理清逻辑之后再动手。这些方法,让我后期写代码的bug越来越少,也越来越有效率。每次解决一个bug,我都能学到一个新的知识点,也能更深刻地理解Java编程的细节。

四、改进建议

结合我三次作业写的代码,还有自己踩过的坑,我从代码规范、功能优化、扩展性三个方面,提出一些自己能实现的基础改进建议。

(一)作业1 改进建议

  1. 代码规范优化:我当时写的get/set方法,命名不规范,比如getcargoWeight,按照Java命名规范,应该大写C,改成getCargoWeight,还有setcargoName改成setCargoName,统一命名规范,能让代码更有可读性,也方便别人查看。

  2. 功能扩展:作业1只实现了货物装载和超载判断,实际航空配载中,可能会有卸载货物的需求,所以可以增加货物删除功能,根据货物名称,删除对应的货物,然后重新计算总重量,判断是否超载。

  3. 异常处理:作业1没有处理非法输入,比如货物重量为负数,虽然作业1没有明确要求,但增加这个功能,能让程序更健壮,也能避免因为非法输入导致程序报错。

(二)作业2 改进建议

  1. 数组扩容优化:我当时在CargoCompartment类里,用固定长度的数组存储货物,最多只能装1000件,实际使用中,货物数量可能超过1000件,也可能少于1000件,用固定数组会浪费内存。可以改成用ArrayList动态集合,按需扩容,节省内存,也更灵活。

  2. 货舱查找优化:当时我用循环遍历的方式查找货舱,当货舱数量比较多的时候,效率很低。可以用Map存储货舱,把货舱ID作为key,货舱对象作为value,这样通过货舱ID查找货舱,直接get(key)就能找到,效率更高,也更简洁。

  3. 输出优化:作业2的输出结果,只能打印到控制台,不能保存,实际使用中,可能需要保存装载记录,方便后续查看。可以增加日志输出功能,把装载结果、货舱状态、航班状态,保存到本地文件中,需要的时候可以打开查看。

(三)作业3 改进建议

  1. 计算类优化:我当时把航空常量,比如空机重量40000.0kg、空机力臂16.25m、旅客舱力臂18.0m,都直接写死在代码里,这样如果后期需要修改这些常量,就得逐行修改代码,很麻烦。可以把这些常量定义为WeightBalanceCalculator类的静态常量,集中管理,修改的时候只需要修改一处,方便维护。

  2. 数据存储优化:作业3中,旅客和货物都是用数组存储的,数组的长度固定,扩展性不好。可以改成用ArrayList动态集合,存储旅客和货物,这样可以灵活添加、删除旅客和货物,不用提前确定数量。

  3. 提示信息优化:当时的非法输入提示,比较笼统,比如只提示“数值不能为负数!”,但不知道具体是哪个输入项出错了。可以优化提示信息,比如“行李重量不能为负数!”“货舱最大载重不能为负数!”,这样用户能快速知道哪里输入错了,也更人性化。

整体系统改进建议

  1. 统一输入管理:三次作业的输入逻辑,都分散在Main类里,代码比较冗余,也不方便维护。可以写一个统一的输入工具类,所有的输入操作,都调用这个类的方法,比如获取航班号、获取货物重量、获取旅客行李重量,这样能减少代码冗余,也方便后期修改输入逻辑。

  2. 增加测试方法:每次测试的时候,都需要手动输入大量数据,很麻烦,也容易出错。可以编写独立的测试方法,提前定义好测试数据,不用手动输入,运行测试方法,就能自动测试所有功能是否正确,提高测试效率。

  3. 界面优化:三次作业都是用控制台输入输出,不够直观,也不贴近真实软件。后期我想学习Swing,做一个简单的图形界面,比如输入框、按钮、显示区域,用户可以通过界面输入数据,查看输出结果,这样更直观,也更有实际意义。

五、总结

(一)学到的知识

  1. Java面向对象核心:通过这三次作业,我真正掌握了类的定义、封装,还有get/set方法的使用,理解了单一职责原则的重要性,也学会了怎么设计多个类,让它们互相协作,完成复杂的功能。以前我只会写简单的线性代码,现在能设计简单的面向对象系统了。

  2. 编程基础能力:我熟练掌握了控制台的输入输出、数组的使用、排序算法(选择排序、冒泡排序)、条件判断、异常处理等基础知识点,也学会了怎么调试代码,定位bug,解决问题。这些基础能力,对我后续学习Java,甚至其他编程语言,都有很大的帮助。

  3. 业务逻辑实现:这是我第一次接触真实的业务场景(航空配载),也第一次把数学、物理公式转换成代码。我学会了怎么理解作业需求,把复杂的需求拆分成一个个小功能,然后逐步实现,最后整合起来,完成整个系统。

  4. 代码规范:我明白了代码规范的重要性,比如类的命名、方法的命名、代码注释,还有类的职责划分,这些都能让代码更清晰、更易维护、更易读懂。以前我写代码,只追求能运行,不注重规范,现在我会刻意按照规范写代码,养成了良好的编程习惯。

(二)不足与待学习内容

  1. 数据结构掌握不熟练:我现在只会用数组,对ArrayList、Map等集合的使用还不熟练,很多功能都不能灵活实现,比如动态添加、删除数据,快速查找数据。后续我会重点学习Java集合,掌握它们的使用方法,提高代码的灵活性和效率。

  2. 异常处理不够完善:我现在只会简单的输入校验,用System.exit(0)停止程序,不能处理更复杂的异常情况。后续我会学习异常处理的相关知识,让程序更健壮,遇到异常的时候,能合理处理,而不是直接停止运行。

  3. 代码调试能力较弱:遇到复杂的bug,我还是只能逐行输出变量值,慢慢查找,效率很低,不会使用IDEA的调试工具,比如断点调试、单步执行。后续我会学习调试工具的使用,提高调试效率,更快地定位和解决bug。

  4. 拓展知识不足:我现在只会写控制台程序,不会做图形界面,也不会实现文件存储、网络通信等功能。后续我想学习Swing、IO流等知识,把这个航空器配载系统,改成可视化、可保存数据的版本,让它更贴近真实的软件。

(三)课程与作业建议

作业设计:三次作业的迭代设计非常好,从简单到复杂,一步步引导我们掌握面向对象编程,每个作业都是上一个作业的升级,让我们能循序渐进地学习,不会觉得难度跨度太大。建议老师以后继续保持这种迭代式的作业设计,让我们在实践中逐步提升。

(四)个人感悟

这三次作业,是我大一上学期最有收获的编程练习,没有之一。从最开始连类都不会拆分,写代码全靠堆逻辑,到最后能设计出符合单一职责原则、多类协作的系统,能实现专业的物理公式计算,我真的成长了很多。

一开始写作业的时候,我经常会遇到bug,有时候一个小bug,能卡我大半天,甚至一晚上,有好几次都想放弃,但每次解决bug之后,那种成就感,又让我充满了动力。我慢慢明白,编程不是一蹴而就的,它需要耐心、细心,更需要不断总结和复盘。每一次踩坑,都是一次成长;每一次解决问题,都是一次进步。

通过这三次作业,我也真正爱上了编程,不再觉得编程是一件枯燥、难学的事情,反而觉得它很有趣,能把自己的想法,通过代码实现出来,能解决实际的问题,是一件很有意义的事情。未来,我会继续努力,把Java基础打牢,多做练习,多总结经验,争取写出更规范、更优秀的代码,也希望能在编程的道路上,一直坚持下去,不断提升自己的能力。

posted @ 2026-05-18 17:11  周昊洋  阅读(9)  评论(0)    收藏  举报