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

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

一、前言

在本次阶段性学习中,我完成了三次Java编程作业,逐步从基础的面向对象编程过渡到较为复杂的航空配载模拟系统。三次作业的知识点覆盖了类与对象、数组操作、排序算法、输入输出处理、聚合关系、以及初步的业务逻辑建模。

· 作业集1(基础货物装载):知识点包括类的定义、对象数组、选择排序、基本输入输出。题量约150行代码,难度较低,主要考查对Java基本语法的掌握。
· 作业集2(多货舱装载):引入了货舱(CargoCompartment)、航班(Flight)聚合关系,以及货物按重量降序排序后匹配目标货舱的逻辑。题量约250行,难度中等,要求理解对象间的关联与协作。
· 作业集3(配载平衡系统):增加了旅客、行李、重心计算、配平评估等复杂业务,涉及多个类的协同工作、输入验证和计算逻辑。题量约350行,难度较高,接近小型系统的开发。

三次作业呈现明显的迭代升级特征,从单一功能到多模块协作,再到完整的业务闭环,对面向对象设计能力提出了逐步提升的要求。

二、设计与分析

【1】 作业集1:货物装载系统
屏幕截图 2026-05-16 164441

  1. 雷达图:除 % Comments 指标为0外,其余指标(平均复杂度、平均深度、最大深度、最大复杂度、每个类方法数、每个方法平均语句数)均处于绿色安全区域,说明代码基础结构良好,无过度复杂的逻辑。
  2. 块深度直方图:绝大多数语句处于嵌套深度2层,少量在1层和3层,无超过4层的嵌套。代码嵌套控制优秀,未出现"箭头型"反模式,结构可读性好。
    代码问题分析
    命名不规范: 变量名 one 、 two 、 three 、 s 、 name1 、 annual 完全无意义
    方法名 SortCargo 、 print_result 不符合Java驼峰命名法
  3. 封装性与设计缺陷
    LoadManifest类设计不合理:
    外部调用 addCargo 时需要传入数组索引 n ,破坏了封装性,外部传入错误索引会导致数组覆盖或空指针
    使用固定大小数组 Cargo[100] 存储货物,无法动态扩容,当货物数量超过100时会抛出数组越界异常
    CargoSorter工具类设计不当: sortCargo 方法应为静态方法,无需创建实例即可调用
    Flight类冗余:无参构造函数公开但未使用
    边界检查:未检查货物数量 n 是否超过数组容量100
    四、代码优点
  4. 基本面向对象思想正确,合理划分了货物、航班、载货清单、排序器等职责
  5. 选择排序算法实现正确(按重量降序)
  6. 代码嵌套深度浅,逻辑流程清晰,无复杂分支
  7. 方法长度适中,未出现"上帝方法"
    【2】 作业集2:货物装载系统

屏幕截图 2026-05-16 170056

屏幕截图 2026-05-16 170050

屏幕截图 2026-05-16 170044

屏幕截图 2026-05-16 170034

屏幕截图 2026-05-16 170028

屏幕截图 2026-05-16 170019

屏幕截图 2026-05-16 170001

  1. 雷达图(Kiviat Graph):所有文件除 % Comments 指标严重偏低(6个文件为0%)外,其余指标(平均复杂度、平均深度、最大深度、最大复杂度、每个类方法数、每个方法平均语句数)均处于绿色安全区域,说明代码的基础复杂度控制优秀。
  2. 块深度直方图:所有文件的语句嵌套深度都很浅,绝大多数集中在1-3层,最深仅6层(LoadDispatcher的选择排序双重循环),完全避免了"箭头型"反模式,代码可读性基础良好。
    四、核心问题分析
  3. 命名不规范:
    方法名不规范: LoadDispatcher.FindCargo  →  findCargo
  4. 输入验证完全未使用:专门编写的 InputValidator 工具类在整个项目中没有被调用一次,所有用户输入均未做合法性检查,输入负数、非数字时程序会直接崩溃。
  5. 固定数组滥用:所有集合都使用固定大小数组(如 Cargo[1000] ),无法动态扩容,元素超过数组大小时会抛出数组越界异常,同时造成内存浪费。
    五、代码优点
  6. 面向对象设计合理,类职责划分清晰,符合单一职责原则。
  7. 方法长度普遍较短,平均每个方法仅2-3条语句,易于理解和维护。
  8. 代码嵌套深度浅,逻辑流程清晰,无复杂的条件分支和循环嵌套。
  9. 基本功能实现正确,包括货物按重量降序排序、货舱匹配、超载判断、状态展示.
  10. 工具类设计正确,所有工具方法均为静态方法,无需实例化即可调用。
    【3】 作业集3:货物装载系统

屏幕截图 2026-05-16 171613

屏幕截图 2026-05-16 171609

屏幕截图 2026-05-16 171604

屏幕截图 2026-05-16 171558

屏幕截图 2026-05-16 171554

屏幕截图 2026-05-16 171551

屏幕截图 2026-05-16 171546

屏幕截图 2026-05-16 171542

屏幕截图 2026-05-16 171532

屏幕截图 2026-05-16 171532

屏幕截图 2026-05-16 171523

  1. 雷达图:所有文件除 % Comments 指标外,其余指标均处于绿色安全区域。
  2. 块深度直方图:所有文件的语句嵌套深度都控制在5层以内,绝大多数集中在1-3层。最深的是 Flight.display() 的5层嵌套,完全避免了"箭头型"反模式,代码可读性基础良好。
  3. 输入验证全面落地: InputValidator 的两个方法在 Main 中被广泛调用,检查所有数值输入是否为非负数,以及货物分配数量是否在合理范围内。

三、采坑心得
坑1:输入处理中的换行符问题
作业1代码:
String name=sc.nextLine();
double maxlode=sc.nextDouble();
sc.nextLine(); // 消耗换行
int n=sc.nextInt();
if(n!=0){
sc.nextLine(); // 条件性消耗换行
}
for(int i=0;i<n;i++){
String name1=sc.nextLine();
double annual=sc.nextDouble();
if(i!=n-1){
sc.nextLine(); // 最后一个不消耗
}
}
踩坑经历:在测试时发现,如果n=0,程序会多读一行或少读一行,导致后续输入错位。原因是nextInt()后遗留的换行符需要处理,但条件判断逻辑复杂容易出错。
正确做法:统一使用sc.nextLine()读取整行后再解析,或统一在每次nextInt()/nextDouble()后执行一次sc.nextLine()。我在作业3中看到sc.next()方式,避免了混合使用,更加可靠。
坑2:数组越界风险
作业1中Cargo[] one = new Cargo[100],若用户输入超过100个货物,程序崩溃。作业2、3也有类似问题。虽然题目可能限制了数据范围,但作为健壮的程序应该使用ArrayList动态集合。
改进:使用ArrayList替代固定数组,可以无界添加。
坑3:排序算法的错误实现
作业1的选择排序:内层循环从j=i开始,导致第一次比较自身。虽然不影响结果,但浪费了一次比较。更严重的是,如果数组中有null元素(如未填满100个),会抛出NullPointerException。因为排序方法接收整个数组长度而非实际货物数量,但实际货物数量为n,排序时应该只对前n个有效元素排序。
坑4:输入验证的边界遗漏
InputValidator.judge2(int a, int b)要求a在1到b之间
四、改进建议
对作业集1的改进

  1. 使用动态数组:将Cargo[]改为ArrayList,避免容量限制。
  2. 改进输入处理:统一使用sc.nextLine()读取每行,然后用split()解析
    对作业集2的改进
  3. 实现Position管理:利用Position类真实记录每个货舱内哪些位置被占用,输出货物摆放图。
  4. 重构display方法:将总重量判断抽取为独立方法,减少嵌套。
    五 总结
    通过这三次作业的迭代开发,我深刻体会到了面向对象设计的演进过程:
    学到的核心知识:
  5. 类的设计原则:单一职责、开闭原则、依赖倒置。作业3中WeightBalanceCalculator独立负责计算,符合单一职责;而Flight承担了过多职责,需要拆分。
  6. 聚合与组合的区别:Flight聚合CargoCompartment(货舱可以独立存在),而Passenger组合Luggage(行李不能脱离旅客)。
  7. 异常处理的重要性:System.exit(0)是反面教材,应该使用异常或返回状态码。
  8. 业务建模能力:从简单的货物清单到完整配载平衡系统,我学会了如何将真实世界的“航班-货舱-货物-旅客-重心”关系转化为类结构。
    对课程的建议:
    · 作业可以增加一个“重构周”,要求对之前的代码进行改进和优化,培养代码维护意识。
    · 鼓励使用Git进行版本管理,每次作业提交代码仓库和Commit历史,便于追踪思路演变。
    · 可以在实验课上展示优秀作业的设计,进行代码走查,学习他人优点。
    这三次作业让我从“能写代码”到“会设计代码”迈出了重要一步。虽然还存在诸多不足,但每一次踩坑都是宝贵的经验。未来我将重点研究设计模式和代码重构技巧,争取写出更优雅、健壮的Java程序。
http://www.jsqmd.com/news/829563/

相关文章:

  • 从零构建智能语音照明系统:硬件选型、电路设计与软件实现全解析
  • 终极NGA论坛浏览体验优化指南:5分钟打造你的专属摸鱼神器
  • 【原理探析】SAR与雷达核心概念:从模糊到聚焦的成像逻辑
  • 蜜度校对通AI智能校对平台:赋能企业宣发物料精准表达与高效传播
  • 保姆级教程:在Ubuntu 22.04上给Tesla M40/P40装NVIDIA驱动(含禁用nouveau完整流程)
  • PDF怎么拆分成一页一页?免费拆分工具方法对比2026 - 软件小管家
  • 用四年时间布局一个不会被短期淘汰的能力组合|2026年真实复盘
  • 终极指南:如何免费获取和使用经典优雅的EB Garamond 12开源字体
  • 如何配置Oracle Managed Data Access的跟踪日志_启用TraceFile排查.NET连库底层报错
  • 主题5:地址与命名——你是谁?在哪里?
  • Windows 11风扇控制难题终极解决:FanControl完整兼容性指南
  • QuickBMS深度剖析:游戏资源提取的终极解决方案与实战指南
  • 基于Adafruit nRF52的BLE Central开发实战:从扫描连接到自定义GATT客户端
  • TickGPTick:基于AI的智能任务管理助手设计与实战部署
  • PDF怎样才能合并成一个?2026年常用的PDF合并工具和方法盘点 - 软件小管家
  • 基于STM32的智能太阳能热水器控制系统设计与实现
  • AgencyCLI:提升开发运维效率的命令行瑞士军刀实战指南
  • RK3576 音视频网络传输总结(RTP / RTSP / UDP / H265)
  • 别再只画拓扑了!用eNSP深度仿真医院网络:业务隔离、高可用与安全接入实战解析
  • Shell 脚本调试技巧:让 Bash 脚本不再神秘报错
  • 如何快速清理Zotero重复文献:智能合并工具完整指南
  • 瑞萨CS+ for CC实战:手把手教你配置BootLoader双程序地址与HEX文件合并(附避坑指南)
  • mysql在事务中执行DDL的后果_MySQL 8.0之前的限制
  • Hailo-8边缘算力实战:从模型编译到Python流式推理全解析
  • 3步掌握CompressO:彻底解决大文件存储难题的智能压缩方案
  • HTTPCanary Magisk模块技术解析:Android HTTPS抓包的系统级解决方案
  • 从仿真到代码:手把手教你用Python+MoveIt API控制UR5机械臂完成多物体抓取搬运
  • SLO-Warden:云原生时代SLO自动化管理的工程实践
  • Excalidraw终极指南:快速掌握免费开源虚拟白板的完整使用技巧
  • SpringCloud Feign服务调用超时,熔断机制失效