当前位置: 首页 > news >正文

面向对象设计与构造----第一单元总结

一、 前言
面向对象课程的第一单元结束了,本单元围绕“航空器配载与货运管理系统”展开,通过三次递进式作业迭代,从基础货运配载逐步演进至完整的载重平衡计算,模拟了航空业中真实、关键的配载业务流程。三次作业分别聚焦基础数据建模、多货舱管理与调度、航空力学配平计算,整体难度呈阶梯式上升。题量适中(每次作业核心逻辑约200~350行),但对工程规范性、鲁棒性、单一职责原则(SRP)提出了严格要求。通过本单元,我从“功能实现”转向“工程设计”,深刻体会到:航空配载系统的核心是精确的重量与力矩管理,而良好的面向对象设计是确保系统安全、可维护的关键。
二、设计与分析

本章节将结合SourceMonitor生成的代码度量报表以及PowerDesigner绘制的类图,对三次作业的源码设计进行深度剖析。

  1. 第一次作业:基础航班货运配载

作业要求​

设计基础航班货运配载模块,记录航班号、最大载重重量,按货物重量从高到低添加货物,实时计算总重量并判断是否超载。

设计思路​

第一次作业是整个系统的基石,核心在于建立最基本的“航班-货物”模型。

Flight类:作为聚合根,封装了航班号(flightNo)和最大载重(maxWeight),职责单一,仅负责航班的基础属性管理。

Cargo类:纯粹的数据实体(POJO),封装了货物名称(name)与重量(weight),不包含任何业务逻辑,符合贫血模型的设计初衷。

CargoManager类:负责货物的管理与总重量的计算。它内部维护一个 List集合,并提供 addCargo()方法。这里我刻意没有直接在 Main类中操作货物列表,而是将这一职责委托给 CargoManager,以降低 Main类的复杂度。

LoadCalculator与 OutputFormatter:这两个是纯工具类(Utility Class),前者负责数值计算,后者负责格式化输出。它们的方法都是静态的,不持有任何状态,体现了“无状态服务”的思想。

主流程通过 Scanner获取数据,但在输入处理上遇到了一个隐蔽的坑:使用 nextInt()或 nextDouble()读取数值后,换行符会被留在缓冲区,导致后续 nextLine()读取货物名称时读到空字符串。

复杂度分析(SourceMonitor)​

根据报表,本次作业代码总行数约为 340 行,平均每个方法 2.36 行,整体结构非常扁平。

屏幕截图 2026-05-17 194923

解读与心得​

CargoManager.addCargo()的基本复杂度(ev(G))为 2,主要是因为需要判断传入的 Cargo对象是否为 null,以及更新内部计数器。这次作业最大的收获不是代码本身,而是对 Scanner 工作机制的理解。为了解决回车吞数据的问题,我查阅了相关资料,最终采用了“先读数值,再用 nextLine()吃回车”的方案,这让我意识到 IO 操作的细节往往比算法逻辑更折磨人。

类图展示​

屏幕截图 2026-05-17 202746

2. 第二次作业:多货舱管理与重量排序装载

作业要求​

扩展为多货舱(如前舱、后舱),每个货舱有最大载重与行列网格位置;按货物重量降序装载,并检查货舱与航班整体是否超载。

设计思路​

第二次作业引入了“空间”概念,系统复杂度显著提升。

新增 Position类:表示货舱中的一个物理位置(行、列),与 CargoCompartment构成了组合关系(Composite Relationship)。这意味着 Position的生命周期完全由 CargoCompartment管理,当货舱消失时,位置也随之消失。在 CargoCompartment的构造器中,我通过双重循环初始化了所有 Position对象。

新增 CargoCompartment类:相比第一次的扁平结构,这次货舱成为了独立的实体。它包含 ID、最大载重、位置列表以及货物列表。它与 Cargo是聚合关系(Aggregation),因为货物可以独立于货舱存在(理论上可以被移到别的舱)。

Flight类升级:现在它持有一个 List,负责管理多个货舱。

引入 LoadDispatcher类:这是本次作业的亮点。为了满足“按重量降序且不能使用 Collections.sort()”的要求,我实现了一个冒泡排序算法。之所以单独设立这个类,是为了严格遵循 SRP——Flight和 CargoCompartment只管“是什么”和“有什么”,而“怎么排”交给 LoadDispatcher。

输入解析阶段变得更加复杂,需要先构建一个货舱映射表(Map<String, CargoCompartment>),然后根据货物指定的目标货舱 ID 进行装载尝试。

复杂度分析(SourceMonitor)

随着功能的增加,代码行数有所上升。报表显示 Flight类开始承担更多的协调工作。

屏幕截图 2026-05-17 195936

解读与心得

Flight.getOverallStatus()的基本复杂度(ev(G))达到了 4,这是因为它需要同时判断“最大起飞重量”与“最大业载重量”的组合情况,逻辑分支较多。为了避免 if-else嵌套过深,我将其拆分为多个卫语句(Guard Clauses)。LoadDispatcher中的冒泡排序虽然算法简单,但在实现时我发现了一个细节:当重量相同时,必须保持输入顺序。因此我在比较条件中加入了 inputOrder的辅助判断,这比单纯的重量比较更符合业务需求。

类图展示​

屏幕截图 2026-05-17 203037

3. 第三次作业:配平计算(V3)

作业要求​

引入旅客与行李(旅客体重75kg+行李重量),新增配平计算:通过力矩计算重心,换算为%MAC并评估安全性(25.0%~38.0%)。

设计思路​

这是本单元最难的一关,引入了物理学概念和严格的工程规范。

新增 Passenger与 Luggage:Passenger的构造器内部必须 new Luggage(),这体现了强制的组合关系。旅客不可能没有行李(哪怕重量为0),这种设计在编译期就杜绝了“无行李旅客”的逻辑漏洞。

新增 WeightBalanceCalculator:纯计算工具类,不持有任何成员变量。这是为了避免“上帝类”。所有计算所需的上下文(Flight对象)都通过 generateLoadSheet(Flight flight)方法参数传入。这种方法耦合度极低,也便于进行单元测试(直接 new 一个 Flight 扔进去算就行)。

常量管理:所有物理常量(空机重量 40000.0、力臂 16.25、MAC 参数等)都定义在 WeightBalanceCalculator中作为 static final常量。

InputValidator强化:本次作业对输入校验达到了“苛刻”的程度。任何负数、超出范围的输入都必须立即 System.exit(0)。我将所有 Scanner的读取操作封装在 InputValidator的静态方法中,确保主流程不被 try-catch污染。

计算流程严格按题目给出的五步:

旅客总重 = Σ(75 + 行李重),力矩 = 总重 × 18.0。

货舱总重与力矩累加。

全机总重与总力矩计算。

实际重心 = 总力矩 / 总重。

%MAC = ((重心 - 15.0) / 5.0) × 100%。

复杂度分析(SourceMonitor & MetricsReloaded)​

报表显示 WeightBalanceCalculator.generateLoadSheet()是核心热点。

屏幕截图 2026-05-17 200705

解读与心得​

WeightBalanceCalculator.generateLoadSheet()的圈复杂度(v(G))为 5,主要开销在于遍历 Flight中的 Passenger列表和 CargoCompartment列表。为了保证精度,我全程使用 double类型,并在输出时通过 DecimalFormat("0.0")统一格式。本次作业彻底禁止了继承、多态、Lambda,这反而让我更专注于“过程式设计的优雅”——通过合理的工具类拆分,即使没有面向对象的花哨特性,代码依然清晰。

类图展示​

屏幕截图 2026-05-17 202514

三、采坑心得

本单元踩坑主要集中在输入校验、边界条件、计算精度三方面,每一次 Bug 修复都是对工程思维的锤炼。

1. 第一次作业:Scanner 回车吞数据

问题: 使用 nextInt()读取货物件数后,直接调用 nextLine()读取货物名称,导致名称被回车符占用,后续数据错位。

数据支撑: 强测中 2 个测试点因输入错位 WA,互测中被 hack 3 次。

解决: 统一输入规范,强制在数值读取后消耗换行符:

int n = Integer.parseInt(scanner.nextLine()); // 先读数值
scanner.nextLine(); // 专门吸收回车
String name = scanner.nextLine(); // 再读字符串
反思: IO 操作永远是新手的大坑,不能假设用户的输入是完美的。
2. 第二次作业:货舱 ID 匹配失败

问题: 输入货舱 ID 时,未严格校验是否与预定义货舱 ID 一致,导致装载到不存在的货舱(返回 null),进而引发 NullPointerException。

数据支撑: 强测中 1 个测试点因 WF(Wrong Format)未通过,互测中被 hack 2 次。

解决: 构建货舱映射表(Map<String, CargoCompartment>),装载前检查目标货舱是否存在:

CargoCompartment target = compartmentMap.get(targetId);
if (target == null) {
System.out.println("货舱ID不存在!");
System.exit(0);
}

反思: 防御性编程(Defensive Programming)不是多余的,外部输入永远不可信。

3. 第三次作业:配平计算数值误差

问题: 最初为了计算快,使用了 float存储重量,导致力矩计算精度丢失,%MAC 偏差超过 0.1%,导致明明在安全范围内的重心被判为“危险”。

数据支撑: 强测中 2 个测试点因配平结果错误 WA,互测中被 hack 1 次。

解决: 统一使用 double存储所有重量与力矩,输出时严格控制格式:

DecimalFormat df = new DecimalFormat("0.0");
System.out.println("重心百分比(%MAC): " + df.format(cgPercent) + "%");

反思: 在航空领域,“差之毫厘谬以千里”。浮点数比较和精度控制是工程计算的生命线。

四、改进建议

基于对三次作业的复盘,我认为代码仍有很大的改进空间,以下是我对后续迭代的一些设想:

1. 设计层面:引入常量接口

当前常量(如空机重量 40000.0、力臂 16.25)分散在 WeightBalanceCalculator中。可以引入 Constants接口,统一定义所有常量,实现接口即可使用,避免魔法数字(Magic Numbers)散落各处。

2. 测试层面:构建自动化测试脚本

目前测试依赖手动构造数据,效率低且覆盖面有限。可基于 Python 构建自动化测试脚本:

使用 random库生成随机输入数据(航班号、货舱参数、货物/旅客信息);

调用 Java 程序获取输出,与预期结果(手动计算或 Excel 验证)对比;

输出测试报告,标记失败用例。

3. 鲁棒性层面:细化输入错误提示

当前 InputValidator仅提示“输入必须在 min 到 max 之间!”,用户体验较差。建议细化错误信息,明确错误位置与期望值,帮助用户快速定位问题。

五、总结

学到的知识:

Java 基础语法(泛型、集合、异常处理)与 Scanner输入处理的细节;

面向对象三大特性(封装、继承、多态)在本单元的应用(虽禁止继承,但通过组合与依赖实现低耦合);

单一职责原则(SRP)的实践:每个类仅负责一项职责,避免“上帝类”;

航空配载的核心逻辑:重量与力矩的平衡管理,以及 %MAC 的安全评估。

需进一步学习:

设计模式(如工厂模式在货物/旅客创建中的应用);

自动化测试工具(JUnit、Mockito)的使用;

更复杂的航空配载场景(如多机型、可变 MAC 参数)的建模。

本单元让我明白: 代码不仅仅是给机器执行的指令,更是人类表达逻辑、解决问题的艺术品。面向对象的核心在于“抽象”,而优秀的抽象能够驾驭复杂性。这为我后续的学习打下了坚实的基础。

http://www.jsqmd.com/news/835830/

相关文章:

  • 上饶装修公司推荐|2026 避坑必看!本土靠谱装修怎么选,这 8 大雷区千万别踩 - 奔跑123
  • code-review-graph 完整上手攻略
  • 贵阳汽车美容洗护改装如何做线上推广?2026全网获客指南与服务商盘点 - 精选优质企业推荐官
  • 2026年5月南充区域广告设计制作(花草牌,小区园林标识,亚克力雕刻)安装价格 - 四川华蔓广告有限公司
  • 哈尔滨:报考中质协六西格玛黑带和绿带指定报考机构推荐 - 众智商学院课程中心
  • 贵阳劳保用品批量供应如何做线上获客?2026全网推广指南与服务商盘点 - 精选优质企业推荐官
  • DeepSeek V4 对于 LLM 应用开发落地到底意味着什么?--中国国内主流大模型 API 供应商横向对比
  • 2026年5月南充区域广告设计制作(标识牌,公示栏,精神堡垒)安装价格 - 四川华蔓广告有限公司
  • 企业知识库 Agent 完整落地教程:RAG + Claude 从架构到生产
  • 居家软装窗帘壁纸如何做线上推广?2026全网获客指南与服务商盘点 - 精选优质企业推荐官
  • 2026年5月南充区域广告设计制作(门头招牌,发光字,软膜灯箱)安装价格 - 四川华蔓广告有限公司
  • 心情又开始有点崩溃
  • 学Java类和对象
  • 四川华蔓广告有限公司设计安装施工|LED显示屏、南充地区一站式制作 - 四川华蔓广告有限公司
  • 2026年4月评价高的防水卷材直销厂家口碑推荐,高分子防水卷材/防水涂料/自粘防水卷材,防水卷材企业找哪家 - 品牌推荐师
  • Java常用类学习(String、StringBuffer、正则、Scanner)
  • 全屋定制家具企业如何做线上推广?2026年AI搜索、短视频与GEO优化指南 - 精选优质企业推荐官
  • 合肥全飞秒医院选择指南|普瑞眼科|安医大|科大眼科等正规眼科推荐 - 品牌速递
  • 徐州:报考中质协六西格玛黑带和绿带指定报考机构推荐 - 众智商学院课程中心
  • Claude Code Hooks 完整开发者指南
  • 2026越南奶茶加盟推荐榜:热门品牌甄选,创业开店优势尽显 - 企业推荐师
  • 四川华蔓广告有限公司设计安装施工|条幅锦旗,楼顶发光字,户外广告牌、南充地区一站式制作 - 四川华蔓广告有限公司
  • 四川华蔓广告有限公司设计安装施工|灯光舞台,演艺主持,泡沫板、南充地区一站式制作 - 四川华蔓广告有限公司
  • 四川华蔓广告有限公司设计安装施工|PVC板雕刻,KT板,车贴、南充地区一站式制作 - 四川华蔓广告有限公司
  • 上海:报考中质协六西格玛黑带和绿带指定报考机构推荐 - 众智商学院课程中心
  • 2026 南京租车怎么选?实测南京万山红遍:全场景适配 + 数据过硬 + 口碑扎实 - 小艾信息发布
  • 团队冲刺第六天
  • 深圳:报考中质协六西格玛黑带和绿带指定报考机构推荐 - 众智商学院课程中心
  • 如何精准选择 GEO 优化运营公司,GEO/AI搜索引擎优化/GEO优化/AI搜索实力优化,GEO优化运营团队口碑推荐 - 品牌推荐师
  • 47.呼和浩特报考CPPM与SCMP,职场进阶优选众智商学院 - 众智商学院课程中心