面向对象程序设计题目集4-6总结
前言
这三次 Java 编程作业都在做数字电路仿真,4、5、6 是递进式开发,后一份代码要兼容前面所有功能再新增需求。整套练习用来巩固 Java 语法、代码检测工具、程序分层、文本解析、输入校验这些课堂内容。
最开始写 4 和 5,我只盯着样例输出,没提前规划代码整体结构,所有逻辑直接堆进主函数,后面加新功能就要多处改代码,调试起来特别麻烦。写到 6 时我直接重写全部代码,按执行步骤拆分开独立方法,前后对比能明显看出前期随手写代码会留下大量返工问题。
| 作业 4(单层基础门仿真) | 作业 5(复合器件扩展仿真) | 作业 6(分层嵌套子电路仿真) | |
| 电路实现范围 | 五种单输出基础门,无多层嵌套、无控制引脚器件 | 新增带控制引脚、多路输出复合器件,区分控制与数据引脚 | 重构代码,支持自定义子电路、多层嵌套、输入报错、拓扑自动展开 |
| 练习重点 | 字符串拆分、循环更新信号、集合排序、静态类使用 | 实体类新增属性、数组存多路信号、多器件分支、差异化打印 | 代码拆分、递归处理嵌套、分层存数据、输入语法校验 |
| 代码总行数 | 363 | 430 | 490 |
| 开发难点 | 主函数过长,没有拆分功能 | 判断分支太多,代码复杂度大幅升高 | 递归容易死循环,分层端口匹配容易出错 |
| 内置数据类数量 | 2 | 2 | 4 |
代码里的文本解析、信号传递、逻辑运算都是手动编写,没有调用现成工具,下面结合 SourceMonitor 度量截图、PowerDesigner 绘制的 UML 类图,梳理整套开发过程里的代码设计、调试问题和优化方向。
一、代码量化与结构分析
用 SourceMonitor 统一检测三份代码,从行数、圈复杂度、分支占比、嵌套深度判断代码质量,所有数值都来自工具导出报表。
| 4 | 5 | 6 | 开发实际感受 | |
| 总代码行数 | 363 | 430 | 490 | 功能增加导致行数上涨,6 拆分多方法,阅读难度更低 |
| 分支语句占比 | 29.0% | 33.3% | 31.3% | 5 支持器件最多,分支占比最高;6 拆分模块后占比回落 |
| 最大圈复杂度 | 34 | 57 | 32 | 4、5 所有逻辑集中在 main,6 重构后最高复杂度出现在递归方法 |
| 单方法平均行数 | 25.67 | 35.20 | 26.73 | 5 主函数达到 152 行,拆分后数值回归合理区间 |
| 平均嵌套深度 | 3.24 | 3.65 | 3.50 | 5 处理多路引脚判断,平均嵌套层级更深 |
| 注释占比 | 0% | 0% | 0.4% | 前两份完全无注释,仅 6 在递归处加一行注释,规范不足 |
1.1 作业 4 代码结构
UML 类图能看出整个程序只有 Main 主类,搭配 PinInfo、Gate 两个仅存数据的内部类,没有独立业务模块,全部逻辑放在静态方法和 main 中,写法偏向面向过程。
方法只简单划分:文本解析、门名称校验、逻辑运算、主流程。main 负责读取输入、运算电路、排序打印,圈复杂度 34,一共 120 行,四层循环互相嵌套,深度 4 的语句有 77 行。


这份代码问题不少,代码耦合度高,新增门电路要同步修改三处逻辑;没有注释,隔几天再看文本截取逻辑很难看懂;超长主函数出现异常时,要通读全部代码才能定位问题。
1.2 作业 5 代码结构
沿用 PinInfo,给 Gate 新增引脚偏移相关字段,新增 createGate 统一创建器件,重载 evaluate 方法适配多路数组输出,但没有拆分臃肿的 main。
为适配九类器件,main 内部堆砌大量 switch 判断,圈复杂度涨到 57,共 152 行,多层循环和条件判断层层嵌套,代码可读性很差。


扩充实体类确实能统一管理器件不同属性,但只修补数据结构、不拆分业务代码解决不了根本问题。每新增一类器件,校验、创建、运算、打印四段代码都要同步改动,调试时常出现部分器件无输出的隐性 bug。
1.3 作业 6 代码结构
吸取前两次教训整体重构,新增 Pin、GateInfo、Sub、SubInst 四类实体类,分层存放引脚、门、子电路定义、子电路端口映射数据。
代码按执行流程拆成五个独立模块:readAll 读取输入、checkErrors 校验语法、getOrMake 与 expandTop 展开子电路、runSim 仿真运算、printOut 打印结果。全局数据统一设为静态变量,不再零散放在 main 局部变量中。
重构后 main 只做流程调度,压缩至 41 行,圈复杂度降至 18,程序最高复杂度集中在递归处理子电路的 getOrMake,圈复杂度 32。


拆分模块后调试方便很多,单一模块出错可以单独测试,不用通读全部代码。分层数据类隔离顶层和子电路信号,不会出现端口命名冲突。不足是递归方法内部 if 分支偏多,还有精简优化空间。
二、开发调试故障复盘
整理三次作业实际调试遇到的问题,梳理故障表现、代码根源和修复手段。
| 故障现象 | 代码根源 | 修复方案 | |
| 作业 4 | 多级串联电路无输出 | 信号循环只遍历一次,无循环终止标记 | 新增 changed 标记,循环运行至无新信号更新再退出 |
| 作业 4 | 同类型门输出排序混乱 | 比较器只判断器件类型,未对比器件数字编号 | 完善比较逻辑,先区分类型,再对比编号大小 |
| 作业 5 | 多路选择器读取不到控制引脚信号 | Gate 缺少引脚偏移字段,读取索引错位 | 新增 ctrlFirst、inFirst 字段,区分两类引脚读取逻辑 |
| 作业 5 | 函数发生器输出格式不符合题目要求 | 打印逻辑统一适配单输出,无多路专属拼接分支 | 新增独立分支,循环拼接多路输出字符 |
| 作业 6 | 多层子电路运行卡死、栈溢出 | 递归无缓存,重复实例化同一子电路造成无限递归 | 新增 Map 缓存已创建子电路实例,复用对象避免重复递归 |
| 作业 6 | 拓扑校验持续报错,端口识别颠倒 | getRole 方法内部输入输出判断条件写反 | 修正判断逻辑,分开处理顶层电路、子电路端口规则 |
| 全部作业 | 隔段时间难以读懂代码逻辑 | 几乎没有注释,变量简写表意模糊 | 解析、运算、递归方法添加单行注释,标注基础功能 |
2.1 超长主函数引发连锁问题
4、5 两份代码把所有业务全部塞进 main,多层循环、判断互相嵌套,输出异常很难快速定位故障区域;新增器件容易遗漏分支判断,部分器件无法正常运算;多层循环变量容易混淆,引脚索引频繁读取错位。6 把 main 简化为调度入口后,这类连锁故障基本消失。
2.2 实体类前期设计缺少拓展空间
4、5 的 Gate 仅适配基础单输出门,后续新增多路、带控制引脚器件只能临时补充字段,底层数据结构反复改动,产生大量重复判断代码。6 提前预判分层、多路使用场景,一次性设计四类实体类,迭代过程不用改动底层存储结构,减少大量返工。
2.3 递归缺少缓存导致死循环
6 早期递归代码没有缓存容器,多层嵌套子电路会反复执行实例化逻辑,最终栈溢出程序卡死。新增全局 Map 存放已生成的子电路实例,递归前先查询缓存,复用已有对象,彻底解决无限递归问题,当初单步调试一下午才找到问题根源。
三、代码后续可行优化方案
结合现有代码缺陷,从架构、方法拆分、编码规范、程序容错四个方向整理优化思路。
| 优化模块 | 现存缺陷 | 优化措施 | 预期效果 |
| 整体程序架构 | 大量静态方法,依靠 switch 区分各类门电路 | 抽象通用门父类,不同门电路编写子类重写运算逻辑 | 新增器件仅需新建子类,不用修改全局多处分支,降低整体复杂度 |
| 递归方法拆分 | getOrMake 内部分支过多,圈复杂度 32 | 拆分端口匹配、实例创建、连线生成三段独立子方法 | 单方法分支数量减少,端口相关故障可单独调试对应代码 |
| 编码规范优化 | 注释缺失,变量命名随意无统一标准 | 长方法添加头部注释,统一驼峰命名,舍弃无意义简写变量 | 降低代码阅读、迭代修改的时间成本 |
| 输入容错优化 | 非法数字输入直接导致程序崩溃 | 数值转换代码外层捕获格式异常,跳过错误行并给出文字提示 | 程序可兼容不规范输入,不会直接终止运行 |
3.1 架构优化思路
当前代码依靠大量分支区分不同门电路,器件越多分支代码越繁杂。后续抽象统一门电路父类,定义通用运算接口,各类门单独写子类实现运算逻辑,运行时直接调用统一接口,省去器件类型判断,从根源减少分支语句。
3.2 编码与容错优化
后续编写代码同步补充注释,统一变量、类命名格式,方便长期维护。所有字符串转数字操作增加异常捕获,碰到非法引脚、错误器件名称时输出提示文字,跳过异常行继续解析剩余输入,提升程序容错能力。
四、阶段总结
三套电路仿真代码完整走完简易堆砌、缺陷暴露、模块化重构的开发流程,借助代码度量工具能客观分辨代码好坏,不再只以程序能否跑通测试用例作为唯一评判标准。
整套练习收获不少,能依靠工具量化判断代码质量;掌握按功能拆分独立方法,明白模块拆分对迭代开发的作用;可根据业务场景设计分层实体类存放数据;排查各类程序故障的调试能力得到提升;学会递归搭配缓存处理多层嵌套结构。
自身短板也很明显,日常写代码很少使用继承、多态简化分支;处理复杂递归不会拆分子方法降低复杂度;前期忽略注释、命名规范;完全没有做输入异常容错设计;没有考虑大规模电路下仿真运行效率优化。
这套作业不只是 Java 语法练习,更是小型软件完整迭代的实操训练。前期只追求快速完成功能的写法存在不少工程层面漏洞,经过三次重构,形成先设计结构、拆分模块、再实现业务的开发思路。本次记录的调试故障、优化思路,后续课程设计、实训项目都能拿来参考,避免重复踩同类问题。

浙公网安备 33010602011771号