作业集1~3的总结性Blog
- 前言
(1)题目一:基础航班货运配载模块
-
难度:基础
-
题量:5个类+主程序
-
核心知识点:
[1] Java 面向对象基础:类、对象、封装(private+getter);
[2] 集合:ArrayList 存储货物;
[3] 排序:手写冒泡排序(重量降序);
[4] 业务逻辑:重量累加、超载判断;
[5] 输入输出:Scanner 处理、格式化输出 (%.1f);
[6] 设计原则:单一职责原则(Cargo/Flight/CargoSorter/LoadManifest 分工明确) -
核心功能:录入航班与货物 → 按重量降序装载 → 计算总重 → 判断超载
(2)题目二:多货舱管理与重量排序装载
-
难度:中等
-
题量:7 个类 + 主程序
-
核心知识点:
[1] 类关系:组合 (Position-CargoCompartment)、聚合 (Cargo-CargoCompartment)
[2] 工具类:LoadDispatcher 排序、InputValidator 校验
[3] 集合与映射:List+HashMap 快速查找货舱
[4] 业务扩展:多货舱独立载重、按目标货舱装载、失败提示
[5] 整体超载判断:同时校验最大起飞重量 / 最大业载重量
[6] 输入处理:多类型混合输入、边界判断 -
核心功能:多货舱配置 → 货物按重量排序 → 分舱装载 → 舱级 / 航班级双重超载判断
(3)题目三:航空器配载与货运管理系统(配平计算)
-
难度:偏难
-
题量:10 个类左右
-
核心知识点:
[1] 纯计算工具类:WeightBalanceCalculator(无成员变量,依赖传入)
[2] 航空专业计算:重量、力矩、重心、% MAC 换算
[3] 输入校验:全覆盖非负 / 范围校验,非法立即退出
[4] 强制要求:禁止 Lambda/Collections.sort,必须手写冒泡排序
[5] 复杂输出:格式化载重平衡舱单、配平安全评估
[6] 新增实体:Passenger、Luggage(强组合关系) -
核心功能:旅客 + 行李重量计算 → 前后货舱管理 → 力矩 / 重心公式计算 → 配平安全判定
2.设计与分析
(1)题目一:基础航班货运配载
我设计了5个类,分别是:Cargo (只管存货物信息),Flight (只管存航班信息),CargoSorter (只管排序),LoadManifest (只管装货、算总重),Main (负责输入输出)

遵守SPR原则,一个类只做一件事。
对第一次题目的代码进行SourceMonitor分析

由此可以看出:最大复杂度和类数为5,代码中没有过多的嵌套,符合单一职责原则SPR;方法短小,功能单一,逻辑简单;代码不会特别臃肿,业务简单。
因此可以看出此代码的一些优点,比如:封装规范,属性都私有,不暴露;手写了冒泡排序;输入输出考虑了回车问题。
但是还有一些小不足:注意到Flight类的属性没有完全私有化,没有做负数校验输入,超载判断比较直接,不够精细。因此部分测试点没有过。
(2)题目二:进阶多货舱管理
这一次代码变得更加复杂,根据题目增加了更多类:Position(表示货舱位置),CargoCompartment(表示货舱,自己管载重),LoadDispatcher(专门排序),InputValidator(做专门检查),Flight(管理多个货舱)
类与类之间的关系相对,货舱与位置关系为组合,货舱和货物是聚合。
以下为PowerDesigner类图

对第二次题目进行SourceMonitor分析:

由此可以看出:类数上升至7变多,但是复杂度依旧不高;分支调用变多,对于多货舱逻辑;代码没有失控,比较干净。
具有部分设计优点:
- 组合 / 聚合关系正确,CargoCompartment 内部创建 Position → 组合关系,Cargo 可独立存在 → 聚合关系
- SRP 执行优秀:排序、校验、装载、货舱完全分离
- 多货舱装载逻辑正确:按重量降序 → 尝试装入 → 成功 / 失败提示
- 双层超载判断:货舱级 + 航班级(起飞重量 / 业载重量)
- 使用 HashMap 快速查找货舱,效率高
但也存在部分问题:货舱状态输出固定写 “正常”,未真正判断货舱是否超载;
InputValidator 只做了简单判断,未全程使用;
缺少对 “目标货舱不存在” 的完善处理;
部分输入混用 next() / nextLine(),健壮性一般;
(3)题目三:配平计算
此次代码在三次作业题目集中最完整,添加了旅客、行李与重心计算:
- Luggage:行李(组合进旅客)
- Passenger:旅客(含标准体重 + 行李)
- Cargo、CargoCompartment:货物与货舱
- Flight:航班(旅客 + 货舱)
- LoadDispatcher:冒泡排序(禁止使用 Collections.sort)
- InputValidator:全流程非负 / 范围校验
- WeightBalanceCalculator:纯计算工具(力矩、重心、% MAC)
- Main:输入、控制、输出舱单
对此次代码继续进行SourceMonitor分析:
![image]()
类数约等于10,符合题目规模;复杂度为2到3,比较低;代码无深度嵌套,逻辑较顺;语句与类方法数合理,方法短小,结构清晰。
可见设计优点: - 完全符合题目禁令:无继承、无接口、无 instanceof
- 强组合关系正确:Passenger 内部 new Luggage,不对外暴露
- WeightBalanceCalculator 纯工具类
- 无成员变量,只做计算,依赖传入 Flight,符合依赖原则
- 输入校验全覆盖:负数立即退出,范围检查严格
- 航空公式计算正确:重量→力矩→重心→% MAC→安全评估
- 强制手写冒泡排序:满足题目算法要求
- 输出专业舱单格式:排版规范、小数统一保留 1 位
对此也有部分缺点:货舱超载警告输出时,当前重量显示为 0.0(未先添加就获取);部分变量命名可更规范(如 r1/c1 可写 frontRow);缺少对 “0 个旅客 / 0 个货物” 的边界兼容;输出空机力臂写死 16.3,应使用常量 16.25 并保留一位小数
这三次作业是一步步升级的:
从最简单的单货舱 → 多货舱管理 → 带旅客、带重心计算的完整配载系统。
我的代码一直保持结构清晰、职责分明、复杂度低,SourceMonitor 的结果也能看出来,我没有写混乱、复杂、难维护的代码。
通过这三次练习,我真正掌握了 Java 面向对象的核心思想,也学会了怎么把真实业务(航空配载)变成规范的代码。虽然细节上还有小瑕疵,但整体设计、规范、思路都完全达标。
3.踩坑心得
对于三次题目集有一些共性问题
- 其中的(1)输入输出问题占bug的百分之五十,主要表现为:nextInt()/nextDouble() 与 nextLine() 混用,导致程序吞掉回车、读不到货物名称、旅客行李重量读取错乱;多次出现 “输入 3 件货物只读到 2 件”“名称读到空串”“程序直接卡死退出” 的现象;负数、0 值、越界值未校验,导致重量为负、货舱行列负数、人数负数等非法数据进入计算。
对此进行思考研究,认为可能是输入流程未遵循:数值输入 → 吸收换行 → 字符串输入 的固定顺序,导致输入指针错位。
按照题目所给的正常输入示例可以正常运行,而边界值或异常输入可能会导致程序崩溃
对该问题进行了多次修复,达到了一定效果并且通过了部分测试点:所以在所有数值输入后必须加 sc.nextLine() 吸收换行符;全程使用 InputValidator 做非负 / 范围检查,非法数据立即退出。
我深刻认识到:控制台程序最容易死在输入,输入不稳,整个程序等于白写。
- (2)类封装与设计问题:主要表现为早期 Flight 等类属性未私有化,外部可直接修改,破坏封装。
题目 3 初期 Passenger 与 Luggage 未实现强组合,Luggage 可被外部创建并修改,不符合 “旅客内部持有行李” 的要求。
部分工具类如 InputValidator 写而不用,职责悬空,未落地到主流程。
计算逻辑与业务逻辑混杂,不符合 SRP。
所以会对类结构产生影响:类职责不清 → 代码难维护 → 扩展时容易牵一发而动全身。
随后进行修复更改,使逻辑更加严谨:全部属性改为 private,只提供 getter;Luggage 在 Passenger 构造器内 new 且不对外暴露;严格坚持 “一个类只干一件事”。
通过三次迭代,我真正理解:好的类设计不是功能实现,而是后期不改不动也能扩展。
- (3)逻辑顺序与计算时序问题,此问题最为致命:货舱超载判断时,先获取重量再添加货物,导致提示信息显示当前重量为 0.0,与实际不符。重心配平计算中,总力矩、总重量、重心、% MAC 计算顺序错乱,导致结果完全错误。题目 2 货舱状态直接写死 “正常”,未用当前重量与最大重量做判断。
具有较为明显的流程图错误:
正确流程:计算总和 → 判断是否超载 → 再执行装载 → 输出状态
错误流程:直接装载 → 输出固定文字 → 不做判断
功能看似运行,但输出错误、状态错误、计算错误,属于 “隐性失分”。
业务逻辑必须严格按题目公式与步骤执行;判断在前,执行在后,不能反过来。
这次经历让我明白:代码能跑 不等于代码正确,逻辑顺序错,一切都错。
- (4)排序算法与题目约束问题,其主要表现为:题目 1 初期冒泡排序方向写反,货物从小到大输出,不符合 “重量从高到低” 要求。
题目 2 使用 Collections.sort 与匿名内部类,不满足题目 3“必须手写冒泡、禁止高级 API” 的约束。
题目 3 货物排序按编号排序,逻辑符合要求,但早期曾出现排序不稳定问题。
明显可见测试结果:输出顺序与样例不一致,直接不符合题目格式要求。
修复后可知:必须逐字读题约束:排序方向、允许使用的 API、算法类型都要严格遵守。
题目要求就是标准答案,哪怕自己写法更简洁,也要按要求来。
4.编码改进建议
结合三次作业的代码结构、SourceMonitor 指标、测试表现,我对整个航班配载系统的长期可维护、可扩展、可复用提出以下真实改进方向:
- 统一输入处理,彻底解决 Scanner 不稳定问题
目前三次作业都是在 Main 里零散处理输入,容易出现换行错乱、重复代码。
建议把所有输入读取、类型转换、非负校验全部封装到 InputValidator 中,做成统一入口,例如 readInt()、readDouble()、readString(),以后任何模块都能调用,不再重复写 Scanner 逻辑,让系统更健壮。 - 把 “状态判断” 放回对应类内部,更符合 SRP
题目 2 货舱是否超载、题目 3 配平是否安全,我都写在了 Main 里。
真正合理的做法是:
CargoCompartment 自己提供 isOverWeight()
WeightBalanceCalculator 自己提供 isSafe()
让类自己管自己的状态,外部只调用结果,不参与判断。这样后续扩展货舱、修改规则时完全不用动主程序,可维护性大幅提高。 - 常量统一管理,避免硬编码散落
题目 3 里的空机重量、力臂、MAC 数值、安全范围等,目前分散在不同类里。
建议建一个 Constant 类,把所有固定数值集中存放,后续航空公司修改标准时,只改一个地方,全局生效,不会出现漏改、错改。 - 增加日志式输出,便于调试与复盘
现在程序只输出最终结果,一旦出错很难定位。
建议加入简单的 “步骤提示”,例如 “正在读取第 N 件货物”“正在计算总力矩” 等,既能方便老师查看执行流程,也方便我自己快速定位问题。
5.三次作业综合总结
这三次航班配载作业是我第一次完整体验从需求 → 设计 → 编码 → 调试 → 提交的全过程,收获非常真实:真正理解了 “类该怎么拆”;掌握了面向对象的核心思想;代码稳定性意识大幅提高;工程规范意识变强;学会用数据看代码质量。
未来还需进一步学习和研究更规范的类设计模式,更健壮的输入与异常处理。
对课程、作业、教学组织的建议:增加测试用例示范;很多时候我们不知道 “该测什么”,如果提供正常用例 + 异常用例示范,我们能更快写出可以通过测试点的代码。


浙公网安备 33010602011771号