OOP三次作业集源码设计与分析总结
写在前面
OOP作业集结束了,面向对象程序设计课程第一阶段学习结束,本阶段以航班货物装载管理系统为核心,采用迭代增量开发的思想,通过三次循序渐进、功能递进的作业不断拓展业务逻辑、优化代码结构,我收获了丰富的知识与实践经验:
熟练掌握 Java 基础语法、集合框架、输入输出处理、静态工具类等核心编程能力;
逐步建立起封装、高内聚低耦合、单一职责等面向对象设计思路;
深刻理解迭代开发思想,从基础货物排序程序逐步迭代升级为综合飞机货运系统,在迭代中优化结构、修复问题,认识到代码可维护性与可扩展性的重要意义;
学会使用 SourceMonitor 进行代码复杂度量化分析、使用 PlantUML 绘制 UML 类图,建立先设计后编码、可量化评估的工程化开发思维。
Complexity Metrics(复杂度分析)
因为下面要用到复杂度分析,所以先在此给出一些相关概念。
我们需要使用的主要是方法和类的复杂度分析。
方法的复杂度分析主要基于圈复杂度的计算。圈复杂度是一种表示程序复杂度的软件度量,由程序流程图中的 “基础路径” 数量得来。
v (G):圈复杂度
用来衡量方法内分支、循环带来的逻辑复杂度,数值越高,代表需要设计更多测试用例才能覆盖全部执行路径。
Avg Complexity (OCavg):类平均圈复杂度
代表项目整体结构的健康程度,数值越低,类设计越简洁、高内聚。
Max Complexity:最大圈复杂度
反映程序中逻辑最复杂的单一方法。
WMC:总圈复杂度
为项目内所有方法圈复杂度之和,用于评估整体维护成本。
Avg Depth:平均嵌套深度
代表 if、for 等语句的嵌套层级,数值越低,代码可读性越强。
第一次作业:
作业要求:
本次作业为航空货运配载系统基础模块,需要实现基础航班货运配载功能。系统记录航班号、最大载重,接收货物信息后,按照货物重量从高到低排序输出,实时计算总装载重量,并判断航班是否超载,保证飞行配载安全。
实现方式:
采用面向对象分层设计,严格遵循单一职责原则,使用ArrayList集合存储货物对象;通过冒泡排序算法实现货物重量降序排列;拆分Cargo、CargoSorter、LoadManifest、Flight、Main五个类,分别负责货物数据封装、静态排序工具、货单管理、航班关联绑定、程序入口与输入输出处理,通过对象协作完成完整业务流程。同时严格处理Scanner输入换行符问题,保证数据正常读取。
代码规模:
第一次作业代码规模如下图。

类图:
第一次作业类图如下,其中 Main 是主类,Flight 为航班类,LoadManifest 为货单管理类,Cargo 为货物实体类,CargoSorter 为独立静态排序工具类。

复杂度分析:
第一次作业的复杂度分析如下。

本次作业共 5 个 Java 类,总代码 105 行,有效执行语句 74 行。项目平均圈复杂度 OCavg=1.33,总圈复杂度 WMC=6.65,最大圈复杂度为 4。
可以看出 CargoSorter.sort () 选择排序方法复杂度最高,v (G)=4,原因是方法内部存在两层循环结构;其余方法均为线性逻辑,圈复杂度为 1 或 2。
整体平均嵌套深度 1.80,分支语句占比仅 12.2%,类之间耦合度低、方法短小精炼,整体代码结构健康;但本次作业注释占比为 0%,缺少业务说明,后期可补充注释提升可维护性。
Bug 分析:
公测:
我的程序在公测中全部通过正确性测试,货物排序、总重量计算、超载判断均符合样例要求;题目要求必须使用选择排序实现货物重量降序排列,使用其他排序算法会导致降序结果出错,我修正为标准选择排序后解决问题;同时在 Scanner 输入处理环节,最初因换行符处理不当,导致货物名称读取为空字符串,经调试添加sc.nextLine()消耗回车符后修复问题。
互测:
在互测过程中,我发现自身代码存在边界逻辑漏洞:最初超载判断条件错误,将总重量 > 最大载重误写为总重量 >= 最大载重,导致刚好满载时错误触发超载警告;同时格式化输出时未严格保留 1 位小数,输出格式不规范。
测试方法:
手动构造多组测试样例,覆盖满载、超载、无货物、单货物等边界场景,验证选择排序降序与配载判断逻辑。
心得
本次作业是航空配载系列作业的迭代起点,通过严格遵循单一职责原则拆分类结构,我初步掌握了面向对象封装思想;同时通过复杂度分析、公测与互测,意识到代码边界逻辑、输入细节处理的重要性,也体会到迭代开发的优势,为后续作业功能扩展与结构优化积累了经验。
第二次作业:
作业要求:
本次作业为航空货运配载系统迭代二,在第一次作业的基础上扩展为多货舱管理与重量排序装载。系统需记录航班整体信息(航班号、最大起飞重量、最大业载重量),管理多个独立货舱(每个货舱有唯一标识、最大载重、行列位置网格);按货物重量从高到低排序后,将货物装入指定货舱,实时检查货舱超载;同时判断航班整体是否超载,输出详细的装载结果、货舱状态和整体配载状态。
实现方式:
采用面向对象分层设计,严格遵循单一职责原则,拆分以下类实现核心功能:
Position:表示货舱中的位置,封装行、列信息,提供位置名称获取方法;
Cargo:表示货物,封装名称、重量、目标货舱 ID;
CargoCompartment:货舱类,管理货舱信息、装载的货物,实现添加货物、计算当前重量、判断超载;
Flight:航班类,管理航班信息和多个货舱,计算整体装载重量;
LoadDispatcher:调度类,实现货物降序排序、目标货舱查找功能;
InputValidator:输入校验类,提供整数、浮点数的范围校验方法。
核心流程:输入航班与货舱信息 → 输入货物信息 → 按重量降序排序货物 → 依次装入目标货舱并检查超载 → 输出装载结果、货舱状态与整体配载状态。
代码规模:
第二次作业代码规模如下图。

类图:
第二次作业类图如下,其中Main是主类,Flight管理多个CargoCompartment,CargoCompartment组合Position、聚合Cargo,LoadDispatcher负责调度排序与查找,InputValidator负责输入校验。

复杂度分析
第二次作业的复杂度分析如下。


本次作业共 7 个 Java 类,总代码 219 行,有效执行语句 161 行。项目平均圈复杂度 OCavg=1.41,最大圈复杂度为 4。
可以看出LoadDispatcher.sortCargos()冒泡排序方法复杂度最高,v (G)=4,原因是方法内部存在两层循环结构;其余方法均为线性逻辑或简单分支,圈复杂度为 1 或 2。
整体平均嵌套深度 1.95,分支语句占比仅 12.4%,类之间耦合度低、方法短小精炼,平均每个类 4.00个方法,平均每个方法 3.86 条语句,整体代码结构健康;但本次作业注释占比为 0%,缺少业务说明,后期可补充注释提升可维护性。
Bug 分析
公测:
我的程序在公测中全部通过正确性测试,多货舱货物装载、货舱超载判断、航班整体超载判断均符合样例要求;但在多货舱 ID 匹配环节,最初未处理目标货舱不存在的边界情况,经补充校验逻辑后修复;同时输入处理时,多货舱信息读取曾因next()与nextLine()混用导致数据读取错误,调整输入读取方式后解决。
互测:
在互测过程中,我发现自身代码存在边界逻辑漏洞:最初航班整体超载判断逻辑错误,仅判断了最大起飞重量,未同时判断最大业载重量,导致部分场景下整体状态输出错误;同时同等重量货物的排序稳定性不足,未按输入先后顺序排列,经调整排序逻辑后修复。
测试方法:
手动构造多组测试样例,覆盖单货舱 / 多货舱、货舱超载、航班整体超载、同等重量货物排序等边界场景,验证装载与判断逻辑;
利用 SourceMonitor 分析代码复杂度,定位高复杂度方法,针对性优化逻辑.
心得:
本次作业是航空配载系列作业的第二次迭代,通过扩展多货舱管理功能,我进一步深化了单一职责原则的理解,学会了组合与聚合关系的实际应用;同时处理多货舱、多维度超载判断的过程中,提升了边界逻辑处理和鲁棒性测试的能力;迭代开发的方式也让我体会到,合理的类设计能让功能扩展更轻松,避免后期重构的麻烦,为后续作业打下了坚实基础。
第三次作业
作业要求
本次作业为航空器配载与货运管理系统迭代三,在第二次作业的基础上新增旅客与行李管理和航空器载重平衡计算功能,实现完整的航班配载与重心评估。系统需记录航班信息、前 / 后货舱信息、旅客及行李信息,计算旅客与货物的总重量、总力矩,换算飞机重心百分比,判断重心是否在安全范围内,并输出详细的载重平衡舱单。
实现方式
采用面向对象分层设计,严格遵循单一职责原则,所有类均无继承与多态,实现以下核心类:
Position:表示货舱中的位置,封装行、列信息,提供位置名称获取方法;
Cargo:表示货物,封装编号、重量信息;
CargoCompartment:货舱类,管理货舱信息、装载的货物,实现添加货物、计算当前重量、判断超载、获取力臂等功能;
Flight:航班类,管理航班信息、多个货舱和旅客,计算整体装载重量;
Luggage:行李类,仅记录行李重量,作为Passenger的组成部分;
Passenger:旅客类,封装旅客姓名和行李信息,计算旅客总重量(含标准体重75kg+行李重量);
InputValidator:输入校验类,提供整数、浮点数的范围与合法性校验方法;
LoadDispatcher:调度类,实现货物降序排序(采用冒泡排序,符合题目要求);
WeightBalanceCalculator:纯计算工具类,实现航空器载重平衡计算的所有核心算法,包括总重量、总力矩、重心、重心百分比计算及状态评估;
Main:主类,负责输入处理、流程调度与结果输出。
核心流程:输入航班与货舱信息 → 输入旅客及行李信息 → 输入货物信息并校验合法性 → 按指定规则分配货物到前 / 后货舱 → 检查货舱超载 → 计算总重量、总力矩、重心及百分比 → 输出载重平衡舱单与配平评估结果。
代码规模
第三次作业代码规模如下图。:

类图:
第三次作业类图如下,其中Main是主类,Flight聚合多个CargoCompartment和Passenger,CargoCompartment组合Position、聚合Cargo,Passenger与Luggage是组合关系,WeightBalanceCalculator作为工具类依赖Flight,InputValidator负责输入校验,LoadDispatcher负责货物排序。

复杂度分析:
第三次作业的复杂度分析如下。
复杂度分析:


本次作业共 10 个 Java 类,总代码 372 行,有效执行语句 282 行。项目平均圈复杂度 OCavg=1.88,最大圈复杂度为 25。
可以看出 Main 主方法复杂度最高,v (G)=25,主要是主方法集中了大量输入校验、多层业务流程分支、货物分配逻辑与流程调度,造成较高逻辑复杂度;其余方法均为线性逻辑或简单分支,圈复杂度为 1 或 2。
整体平均嵌套深度 1.84,最大嵌套深度 5,分支语句占比 13.5%,类之间耦合度低、方法短小精炼,平均每个类 4.30 个方法,平均每个方法 4.58 条语句,整体代码结构健康;但本次作业注释占比为 0%,缺少业务说明,后期可补充注释提升可维护性。
Bug 分析:
公测:
我的程序在公测中全部通过正确性测试,旅客行李计算、载重平衡配平、货舱管理均符合样例要求;但在货物装载逻辑中,未正确实现超重拦截功能,货舱超重时仍直接添加货物,导致货舱当前重量统计异常;同时输入范围校验错误,货物数量校验区间误写为 0 到 m,实际业务要求为 1 到 m,经修正逻辑后修复问题。
互测:
在互测过程中,我发现自身代码存在边界逻辑漏洞:货物装载流程错误,先执行添加操作再判断超载,造成货舱重量重复累加;同时输入校验边界错误,未按要求限定货物数量合法范围为 1 到 m。
测试方法:
手动构造多组测试样例,覆盖货舱超载、输入边界值、旅客空值、货物空值等边界场景,验证装载与配平判断逻辑;
利用 SourceMonitor 分析代码复杂度,定位高复杂度方法,针对性优化逻辑。
心得:
本次作业是航空配载系列作业的第三次迭代,通过引入旅客与行李管理、航空器载重平衡计算,我进一步深化了单一职责原则的理解,学会了组合与聚合关系的实际应用;同时处理航空业务核心逻辑的过程中,提升了对复杂业务流程的拆解能力和边界逻辑处理能力;迭代开发的方式让我体会到,合理的类设计能让功能扩展更轻松,为后续更复杂的航空配载系统开发打下了坚实基础。
关于设计模式的思考:
在完成第一单元三次作业的开发时,我尚未系统学习工厂模式等设计模式相关知识,同时严格遵守作业约束:全程不使用继承、接口与多态,完全依靠类之间的组合、聚合、依赖关系以及单一职责原则完成系统架构设计。
在全部迭代开发结束后,从老师那学习了设计模式内容,理解了工厂模式、桥接模式等范式的设计思路与适用场景。我也更加意识到,本次作业中组合优于继承、工具类解耦、高内聚低耦合这些基础面向对象设计思想,是系统能够稳定迭代、便于维护的关键。
后续学习中,我会继续规范类间关系设计,主动结合业务场景运用设计模式优化代码,进一步提升代码的可扩展性、健壮性与可维护性。

浙公网安备 33010602011771号