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

JavaOOP第一阶段总结

一、前言

OOP学习的第一阶段结束了,在第一阶段学习中,我们学习了OOP的类的定义与使用,了解了封装性和解耦合的重要性。
在前三次题目集中,主要是围绕着航空器的货物装载问题,来保证飞行安全。这三次题目集,一次次迭代,从易到难,很能锻炼我们对封装性的理解,对MVC模式的使用。而且以飞行安全为题还具有学校特色。
总的来说,题目难度的梯度比较合理,知识点较为简单:类与对象封装等。


二、设计与分析

1、 OOP题目集1

本题题目背景是:在航空业中,航班起飞前需要进行严格的“配载”,即计算飞机的旅客、货物、行李的重量分布,计算出飞机的重心位置,以确保飞行安全。
题目要求设计一个基础的航班货运配载模块。

类图

类图

其中Main是主类,Flight是飞机类,Cargo是货物类,GrandCrew是地勤人员类,CargoSorter是货物排序的工具类,LoadManifest是装载货物的类,CalculateTotalWeight是计算货物总重的工具类。

如图,在设计过程中尽量使用依赖关系来降低各个部分的耦合性,除了题目规定的关联关系之外,都在努力使用依赖进行解耦合。

以下是题目要求的部分类图:
题目类图

复杂度分析

复杂度图

可以看到,在主方法里有23条语句,单方法承担的比较重的负担。
而且块深度分布较深,嵌套过深,逻辑易混乱。

总结

在整个编码过程中,会尽量使用封装来进行分块,但是在每个方法中嵌入了过多的语句,使代码逻辑易于混乱。在以后的编码过程中尽量使用MVC模式进行构建。

2、OOP题目集2

本题题目背景是:航空公司要求进一步细化配载管理。飞机不再只有一个货舱,而是分为多个货舱(如前舱、后舱等)。每个货舱有独立的最大载重和固定数量的装载位置(行列网格)。地勤人员需要按照货物重量从高到低的顺序,将每件货物选择放入某个货舱,系统需实时检查该货舱是否超载。同时,系统需要记录航班整体的最大起飞重量和最大业载重量,并判断整体是否超载。
题目要求在题目集1的基础上扩展一个航班货运配载模块。
在设计方面,必须遵守SRP

类图

类图

其中Main是主类,Position是位置类,Cargo是货物类,LoadDispatcher是一个调度类(对货物进行排序和查找),CargoCompartment是一个货舱类,Package是一个封装Cargo和目标舱的包类,Flight是一个飞机类,InputValidator是输入校验类,Input类用于管理输入部分,Output用于输出管理。

如图,为了实现题目要求的SRP,我将输入输出从Main类中分离出来,封装成单独的Input、Output类,让Main类只负责逻辑运行,不参与输入与输出的过程。
并且每个类除了他们改知道的部分外都是使用依赖进行解耦合,增强代码可复用性。

在类设计中,也遵循了以下要求

在CargoCompartment类中要聚合Cargo,Position类,CargoCompartment 创建时内部生成 Position 列表

以上操作使代码更具有条理,符合题目要求。

复杂度分析

复杂度图

如图,可以看到,最大圈复杂度为4,平均复杂度为1.44,代码的复杂度处于安全区间。
代码块的最大深度为5,平均深度为1.71,说明嵌套逻辑较少,处于合理范围。
整体复杂度较题目集1改善较大,有所进步。

结构方面,9个类共包含44个方法,平均每个类4.89个方法,方法平均语句占2.23行,结构设计较为合理,符合SRP

但是在LoadDispatcher类中的 sortCargos() 方法复杂度较高,由于采用的是冒泡排序,有多重for循环嵌套,导致复杂度较高。

总结

在整个编码过程中,尽量扣紧SRP要求,降低代码的耦合性和复杂度。相较题目集1,在代码逻辑方面有所改善,并了解到SRP对代码复杂度的重要性。

3、OOP题目集3

本题题目背景是:但在真实的航空业务中,飞机的装载不仅包含货物,还包含旅客及其随身行李。更关键的是,任何装载都必须经过严格的“载重平衡”计算,得出飞机的重心位置,以确保飞行安全。在航空器配载中,所有装载项(旅客、前舱货物、后舱货物)都有其对应的力臂。重量乘以力臂等于力矩。所有力矩之和除以总重量,即为飞机的实际重心。为了统一标准,实际重心需要换算为占平均空气动力弦(MAC)的百分比。
题目要求在前两次题目集的基础上新增一个计算工具类,为了计算飞机的实际重心,保证“载重平衡”,来保障飞行安全。
在设计方面,要遵循题目给定的关系,在类设计方面,使用SRP,并且严禁使用继承和多态。

类图

类图

其中Main是主类,Position是位置类,Cargo是货物类,LoadDispatcher是一个调度类(对货物进行排序和查找),CargoCompartment是一个货舱类,Package是一个封装Cargo和目标舱的包类,Flight是一个飞机类,InputValidator是输入校验类,Input类用于管理输入部分,Output用于输出管理,Passenger是乘客类,Luggage是行李类,WeightBalanceCalculator是一个计算工具类。

在类设计中,已遵循以下要求:

新增类 职责划分 类间关系设计建议
Passenger 仅负责管理旅客姓名及计算旅客总重量(含标准体重) 与 Luggage 是组合关系。旅客登机必带行李(可为0kg),行李对象必须在 Passenger 构造器内部 new 出来,不对外暴露修改
Luggage 仅负责记录行李重量 作为 Passenger 的组成部分,体现类的细粒度拆分
WeightBalanceCalculator 纯计算工具类。仅负责根据航空力学公式计算总重量、总力矩、重心及百分比。 与 Flight 是依赖关系。该类不应有 Flight 的成员变量,必须将 Flight 对象作为 generateLoadSheet 方法的参数传入
InputValidator (优化) 剥离所有控制台的异常处理逻辑,提供统一的获取整数、浮点数的静态方法 与主流程是依赖关系

原有的 Flight 类需增加 List<Passenger> 属性,体现关联关系。原有的 LoadDispatcher(排序)在本次生成报告时需被内部调用。

复杂度分析

复杂度图

如图,可以看到,平均圈复杂度为1.65,表明代码逻辑整体清晰,分支结构简单,符合可维护性要求,最大圈复杂度为6,在InputValidator类的 readIntRange() 方法中,复杂度较高。
最大块深度为6,与最大复杂度一致,该方法由于含多重嵌套 if 判断,复杂度和块深度较大,平均块深度为1.95,整体结构较为合理。

结构方面,代码整体含7个类,平均每个类4个方法,符合SRP,平均语句数为2.93,较为细化。

总结

在整个编码过程中,尽量扣紧SRP要求,降低代码的耦合性和复杂度。相较题目集1, 2,在代码逻辑方面有所改善,并了解到SRP对代码复杂度的重要性,在进行新类的添加时,感觉较为方便,说明各个模块的耦合性较低。


三、踩坑心得

在写代码的过程中哪有不踩坑的捏,在完成三次题目集的过程中,犯了一些错误,踩了一些坑,现在复盘的时候回头看看。

1. 第一次题目集

在第一次提交时,没有关注到超载部分,只注重于输出结果与样例一致。这种过分执着于 “面向结果编程” 的错误,导致忽视了在测试中的边界测试。
而在改代码时,只注意了测试点中占比较大的超载部分测试,又忽视了排序的实现,结果在提交时才注意到这个部分。
增加排序时,由于不是很熟练,再加上赶着完成作业的急切心理,结果连在上学期学C语言时十分熟练的排序都写错的好多遍,包括冒泡、选择等排序方法。

在提交成功后,显示答案正确的红字出现,松了一口气的同时,我又在想我写的这个有没有能改进的地方,回忆起上课时说的 SRP我感觉还能再改改,但是改完又开始重复这个问题。也许是完成作业了,那种急切感没了,脑子就冷静下来了。一直到在床上睡觉都在想这个问题。

第二天,老师说,只以第一次提交正确为准,我意识到这种急切感不对。

因此在后两次题目集中我会尽量优化好后才会提交,将每一次提交当成最后一次,或许这样能提高我的代码质量吧。

2. 第二次题目集

由于有第一次题目集的教训,我在提交时会尽量考虑全面,因此在初次提交时的正确性要显著高于第一次。嘻嘻 由于第二次题目集没有了测试点的提示,所以只能自己在考虑时尽量更全面。但是在一次次更改中,发现自己的代码不是太符合题目要求的 SRP 。因此在不知道更改哪里时,决定重构一下代码,使其更符合SRP

在一次次更改过程中,试着改过判断超载的判断,改过输出。而且还在思考 Position 类的作用,毕竟使用 Position 进行列表限制时,会导致和题目示例的输出不一致,所以到最后我都没有明白Position类的作用。

其实在最后发现是输出中的中文输出错误,真是 诶,没招了,好在提交正确了。

因此在后续过程中试图注意这部分,但是根据第三次的结果来看,还是没有长记性。

3. 第三次题目集

在完成第三次题目集的过程中,我有一个比较疑惑的地方,题目明明要求排序来着,但是我如果调用 LoadDispatcher 中的排序就会错。

好了说回第三次题目集,初次提交时也是吃了第一次的教训 (在后面看来并没有嘛) ,检查了感觉是比较符合自己检测就提交了。由于整体框架是继承自题目集2的,因为在写第二次的时候重构了来着,所以在添加新类时十分方便,输入和输出也只需要更改InputOutput(感谢第二次中决定重构的自己)

说来也是,由于输出部分太多,导致自己没有看清楚,题目的样例也只有正确的一个,因此输出错误答案时也没有太过于小心,导致查看了很多遍。

在实现以下需求时,由于没有注意到带范围的值只有在超出范围才输出第二种,小于0还是第一种输出,在这个方面也纠结了好久。

所有检测到输入的数值如果为负数,则输出数值不能为负数!,程序停止运行
如果检测到输入的数值超过应有范围,则提示输入必须在 最小值 到 最大值 之间!,程序停止运行

而实现以下需求时,由于不了解当前载重要不要停止,载重值是装前还是装后的,也折磨了一段时间。

前舱装载量超过最大装载量,提示:!!! 警告:[1]剩余容量不足(当前载重_载重量值/最大载重量_kg),请重新分配或减轻重量!
后舱装载量超过最大装载量,提示:!!! 警告:[2]剩余容量不足(当前载重_载重量值/最大载重量_kg),请重新分配或减轻重量!


四、总结和建议

经过这三次题目集,对面向对象编程的封装相关部分有了些许了解。
我的代码经三次迭代,较第一次相比,代码的 SRP 部分更合理了,并且由于输入,输出和对象的组装部分从 main 函数分离出来,使其在扩展方面更好,可以持续改进这段代码。

在OOP第一阶段的三次题目集中,感觉对类的封装部分了解较好,但是在类的职责分配方面不是很擅长。由于体会到了 SRP 也就是解耦合在迭代过程中的好处,感觉会在学习中持续尝试 SRP 等解耦合的方法,进一步了解面向对象设计。

在下一阶段应该就是 继承多态 的使用,希望体会继承和多态在面向对象设计中的强大之处。
以及 SOLID 等原则在设计中的妙处。

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

相关文章:

  • 2026年语音转写做总结:如何让程序员告别“无效加班”
  • B站视频下载终极指南:免费获取4K大会员高清视频
  • 邮件安全网关怎么选?三种类型网关和功能对比全面解析
  • Memoria-智能影记创新实训博客(八):本地优先设计下的隐私保护与云端大模型协同
  • 基于ARM Cortex-A53核心板的智能运动控制系统设计与实践
  • 使用taotoken后c语言服务调用大模型api的延迟与稳定性实测观感
  • 淡化眼角鱼尾纹的护肤品推荐 熟龄肌闭眼入|CA逆时光抗皱不踩雷 - 全网最美
  • 别再死记硬背递推公式了!‘爬楼梯’这道题,我用动画和现实例子帮你彻底搞懂递归
  • 植物表型分析系统产品介绍和厂家推荐 - 品牌推荐大师
  • 构建反测试剧场防线:识别脆弱测试与提升软件质量实践
  • Linux硬件监控终极指南:如何用lm-sensors守护你的系统健康
  • TSL2561高精度光照传感器在可穿戴设备中的集成与应用指南
  • 汽车嵌入式软件自动化测试:从ISO 26262到HIL的实战指南
  • 本地AI助手集成开发环境:多模型管理与提示词工程实践
  • 文档怎么转PDF?2026常用转换方法和软件对比 - 软件小管家
  • 从Vivado到上电启动:手把手教你用Petalinux 2022.1为Zynq Nano板卡制作可启动SD卡
  • 别慌!Pygame里time.sleep()报错?用Clock.tick()轻松搞定(附完整代码示例)
  • 植物水势测量仪产品介绍和厂家推荐 - 品牌推荐大师
  • OpenCrow分布式爬虫调度系统:从架构设计到部署实战
  • 基础分析仪:N9020B| 是德科技Keysight
  • PDF怎么转Word?2026年免费转换工具对比|在线转换方案全面测评 - 软件小管家
  • Prompt工程实战:从技巧到系统化工作流设计
  • Vivado 2021.2之后,System Generator去哪了?手把手教你用Vitis Model Composer找回它
  • 终极指南:如何用OpenBoardView免费开源工具轻松查看和分析PCB电路板文件
  • 2026工业零部件清洁度萃取设备新标杆,西恩士清洗设备引领国产替代 - 工业设备研究社
  • 2026年4月山西省正规的商用净水设备实力厂家推荐,净水维修服务/净水器服务/净水安装服务,商用净水设备公司推荐 - 品牌推荐师
  • 京东自动评价工具:Python智能购物助手终极指南
  • 对比直连与聚合接入在延迟体感上的实际差异
  • 2026年义乌高端灯具甄选指南:无主灯设计与全屋灯光深度评测 | 西顿照明金华总经销别墅无主灯定制防眩护眼灯酒店工程照明商业空间灯光三年质保终身售后 - 企业品牌优选推荐官
  • ContextGit:基于Git钩子与AI的智能提交上下文增强实践