第一次blog作业

一、前言
三次作业围绕"航班货物装载与载重平衡系统",由浅入深引导我们从过程式编码过渡到结构合理的面向对象设计:

image

二、设计与分析
2.1 作业集 1
作业集 1 已将系统拆分为 5 个类,每个类有明确职责:

image

类图:
image

流程图:
image

复杂度分析图:
image

输入采用 nextLine() + Double.parseDouble() / Integer.parseInt() 统一读取,避免了换行符残留问题。

存在的问题:虽然已有类拆分和封装,但排序仍为手写 O(n²) 冒泡,getCargos() 直接返回内部 List 引用,外部可修改内部数据,封装存在漏洞。

2.2 作业集 2

image

类图:
image

流程图:
image

复杂度分析:
image

封装改进:作业集 1 的 Cargo.name 为 public,外部可直接赋负数;作业集 2 改为 private + getter,外部只能读取不能修改。

排序改进:Collections.sort() + Comparator 匿名类,4 行完成降序排序,O(n log n) 替代 O(n²) 冒泡。

双重量限制:maxTakeoffWeight(物理极限)与 maxPayloadWeight(法规限制)后果不同,需分别判断——类设计应反映业务真实情况。

2.3 作业集 3 —— 9 类 + 载重平衡
新增需求:旅客标准体重 75kg + 行李、前后双货舱(力臂不同)、CG/%MAC 计算及安全区间 [25%, 38%] 判断。

核心计算逻辑:

image

类图:
image

流程图:
image
复杂度分析:
image

不足:作业集 3 的 LoadDispatcher 回退到手写冒泡,未复用作业集 2 的 Collections.sort,反映出代码复用意识不足。

超载策略:作业集 2 拒绝装载(返回 false),作业集 3 警告但继续装载——后者更贴近实际航空业务,超载判定交由舱单评估。

三、采坑心得

  1. Scanner 换行符残留:三种 Scanner 方法混用导致数据错位,统一为 next() 系列后解决。

  2. OJ 输出格式:空格数量、小数精度(%.1f vs %f)、中文全角标点——必须逐字符与样例对比。

  3. 编译错误:类名与文件名不匹配、方法名大小写错误、缺少 import 语句,初学阶段反复出现。

  4. 组合 vs 聚合:航班取消后货舱不复存在(组合◆),但旅客仍独立存在(聚合◇)——区分关键在于生命周期依赖。

  5. 浮点精度:%MAC 边界判断需引入微小容差(如 1e-6),避免浮点误差导致误判。

四、改进建议

  1. 统一排序:全部改用 Collections.sort() 或 List.sort(),不再手写冒泡。

  2. 改用异常处理:System.exit(0) 改为 throw new IllegalArgumentException(),由调用方决定处理方式。

  3. 统一接口:CargoCompartment 构造方法参数顺序和类型应跨作业集保持一致。

  4. 保护内部状态:getCargos() 应返回 Collections.unmodifiableList(),防止外部修改内部数据。

  5. 引入策略模式:支持多种排序方式时,可抽象 SortStrategy 接口,灵活切换。

  6. 增加单元测试:对 addCargo()、sortCargos()、CG 计算等核心方法编写 JUnit 测试。

五、总结
我主要学到了封装的本质是数据保护(private + getter),SRP 的价值是修改隔离,组合与聚合需区分生命周期依赖,标准库应优先使用,代码设计应对齐业务含义。
从过程式到面向对象,核心转变不是语法,而是设计思维方式——这是三次作业最重要的体会。

posted @ 2026-05-18 21:23  three-j  阅读(7)  评论(0)    收藏  举报