作业集1~3的总结性Blog

  1. 前言
    (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 (负责输入输出)
image

遵守SPR原则,一个类只做一件事。
对第一次题目的代码进行SourceMonitor分析
image
由此可以看出:最大复杂度和类数为5,代码中没有过多的嵌套,符合单一职责原则SPR;方法短小,功能单一,逻辑简单;代码不会特别臃肿,业务简单。
因此可以看出此代码的一些优点,比如:封装规范,属性都私有,不暴露;手写了冒泡排序;输入输出考虑了回车问题。
但是还有一些小不足:注意到Flight类的属性没有完全私有化,没有做负数校验输入,超载判断比较直接,不够精细。因此部分测试点没有过。

(2)题目二:进阶多货舱管理
这一次代码变得更加复杂,根据题目增加了更多类:Position(表示货舱位置),CargoCompartment(表示货舱,自己管载重),LoadDispatcher(专门排序),InputValidator(做专门检查),Flight(管理多个货舱)
类与类之间的关系相对,货舱与位置关系为组合,货舱和货物是聚合。
以下为PowerDesigner类图
image
对第二次题目进行SourceMonitor分析:
image
由此可以看出:类数上升至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.三次作业综合总结
这三次航班配载作业是我第一次完整体验从需求 → 设计 → 编码 → 调试 → 提交的全过程,收获非常真实:真正理解了 “类该怎么拆”;掌握了面向对象的核心思想;代码稳定性意识大幅提高;工程规范意识变强;学会用数据看代码质量。

未来还需进一步学习和研究更规范的类设计模式,更健壮的输入与异常处理。

对课程、作业、教学组织的建议:增加测试用例示范;很多时候我们不知道 “该测什么”,如果提供正常用例 + 异常用例示范,我们能更快写出可以通过测试点的代码。

posted @ 2026-05-18 15:30  ariko  阅读(9)  评论(0)    收藏  举报