关于三次迭代作业模拟电路个人心得
一、前言
本次阶段性总结覆盖迭代编程课程作业 4、作业 5、作业 6 三项独立递进开发任务,三份代码依次迭代、功能逐层拓展,三者共享同一电路仿真核心业务,但代码结构、实现逻辑、支持器件、解析能力存在清晰边界区分。本文将分开梳理三次作业各自的知识点、代码规模、开发难度,结合三份独立源码的 SourceMonitor 量化报表、分阶段 PowerDesigner 类图、各版本专属运行流程图完成完整复盘,客观对比三套代码的优劣差异,梳理每一段编码过程中的收获与缺陷。
三份作业代码为逐步叠加迭代关系,并非完全独立项目:作业 4 是初代基础版本,仅实现单层基础门电路;作业 5 在作业 4 完整代码基础上新增复合器件、优化信号传播逻辑;作业 6 完全重构数据存储层,新增子电路解析、递归求值、全局语法校验模块,对前两版全局静态变量耦合问题做彻底改造。下文将分开介绍三套代码的开发定位与基础概况。
作业 4 代码核心定位为 Java 面向对象基础实操,全套代码仅实现与门、或门、非门、异或门、同或门五类基础二输入逻辑器件,仅支持单层无分层电路,不存在复合控制引脚、多路输出、子电路语法。代码全部使用全局静态数组存储引脚、输入、连线数据,未封装独立实体类,仅包含抽象 Gate 父类、5 个门子类、1 个 Main 运行类,无专门信号解析实体。借助 SourceMonitor 单独统计,作业 4 有效代码 426 行,7 个类、21 个成员方法,方法平均圈复杂度 4.1,无递归逻辑,全部为单层顺序循环。难度最低,核心考察继承多态、数组状态管理、单层信号迭代传播,仅需处理外部输入、门输入引脚、门单输出引脚三类信号格式。
作业 5 代码是作业 4 的拓展升级版,完整保留作业 4 所有基础门代码,在此之上新增三态缓冲门、译码器、多路选择器、分路器四类复合器件,新增控制引脚、多路输出两套存储逻辑,拆分单输出outSingle与多输出outMulti两套数组,重构信号传播propagate函数,增加最大迭代次数规避环路死循环。该版代码依旧沿用全局静态数组,但抽取parsePin、calcGate通用工具方法,减少重复代码。单独统计有效代码 782 行,新增 4 个器件子类、1 个引脚解析实体类,类总数 13 个,方法 43 个,平均圈复杂度 6.7,存在多层分支嵌套逻辑。难度中等,重点区分单输出 / 多输出器件寻址规则,需要处理带使能控制引脚的特殊运算逻辑,边界测试用例数量较作业 4 提升一倍。
作业 6 代码为全新重构综合版本,完全抛弃作业 4、5 全局静态数组存储方案,独立设计Circuit电路、Conn连线、EvalResult仿真结果三大实体类,新增Pin器件引脚、SubPin子电路端口两类解析实体,实现自定义电路脚本解析引擎,支持Cx:子电路、endc结束标记、跨层级Cx-端口信号传递,新增全局validateCircuit语法校验、递归evalCircuit分层求值模块。单独统计有效代码 1247 行,类总数 18 个,方法 65 个,核心递归求值方法圈复杂度 12.3,引入递归算法、拓扑依赖排序、哈希映射状态管理。难度最高,完全脱离前两版简单单层仿真框架,需要自主设计词法解析规则、多层递归边界控制、全局信号冲突检测,是小型解释器级别的完整工程代码。
三者难度、代码体量、知识点形成清晰递进关系,作业 4 侧重基础面向对象语法,作业 5 侧重分支拓展与边界循环控制,作业 6 侧重工程分层、递归算法、自定义脚本解析,三份代码完整记录本人从基础编码到小型工程开发的完整成长轨迹,下文将分开对三套代码做独立设计分析、分阶段踩坑复盘。
二、设计与分析
2.1 作业 4 初代代码架构独立分析
作业 4 代码架构极简,仅分为两层:抽象逻辑器件层、主程序全局调度层,无独立数据实体封装,全部电路数据依托 Main 类静态全局数组存储。
逻辑器件层仅包含抽象父类Gate,统一声明compute()、isValid()、print()、type()抽象方法,AndGate、OrGate、NotGate、XorGate、XnorGate五个子类继承并重写方法,所有门仅支持 1 路输出引脚-0,输入引脚仅支持 1、2 号引脚,不存在多路输出、控制引脚相关成员变量。Gate父类仅定义pin[]单个数组存储输入引脚电平,仅存在outSingle单一整型变量存储输出,无outMulti多路输出数组。
主程序调度层依靠静态数组inputName、inputVal存储外部输入,lineStart、lineEnd、lineCnt存储连线信息,全局静态列表存储所有门对象。运行流程仅有单层循环:读取 INPUT 输入、解析连线填充门引脚、单层 while 循环迭代更新电平、最后按门类型顺序打印输出,无分层、无递归、无语法校验逻辑。
对应单独生成的作业 4 PowerDesigner 类图可见明显局限性:所有数据与业务逻辑耦合在 Main 类,全局静态变量数量多、耦合度极高;Gate 子类功能单一,仅适配二输入基础门,无拓展复合器件预留设计;不存在信号合法性校验流程,非法连线、多驱动信号会直接造成电平错乱,程序无报错提示。代码优势是逻辑简单、上手快速,适合入门练习面向对象继承;缺陷是拓展性极差,新增器件、分层电路必须大规模重构全局数组。
2.2 作业 5 拓展版代码架构独立分析
作业 5 完整复用作业 4 Gate 基础门子类,仅在抽象父类Gate中新增outMulti[]多路输出数组、ctrlCount控制引脚计数、outCount输出引脚数量成员变量,新增TriGate、DecoderGate、MuxGate、DemuxGate四个复合器件子类,单独适配带控制引脚、多路输出的器件运算规则。
数据存储依旧沿用 Main 全局静态数组,但新增parsePin()、gateInputCount()、calcGate()静态通用工具方法,将重复的引脚字符串拆分、门参数提取、电平计算逻辑抽离,大幅减少作业 4 中的重复代码。信号传播模块完全重构propagate()函数,区分单输出门、多路输出门两种更新逻辑,更新下游引脚前统一重置引脚为未知状态;仿真循环新增最大迭代次数常量,解决环路电路无限循环卡死问题。
单独对比作业 5 SourceMonitor 报表,相较作业 4 重复代码占比从 31% 下降至 17%,但仍未脱离全局静态存储的局限。对应专属类图可见改进与不足:Gate 父类完成拓展改造,兼容单输出、多路输出、控制引脚器件,开闭原则优于作业 4;但所有工具方法依旧全部存放在 Main 主类,静态方法与全局数组深度耦合,无法单独复用;依旧无独立电路、连线实体,所有连线、输入数据零散分布在静态数组中,代码可读性差;无语法校验模块,输入脚本格式错误依旧会直接抛出数组越界、数字转换异常。
2.3 作业 6 重构版代码架构独立分析
作业 6 完全舍弃作业 4、5 全局静态数组存储模式,从零搭建分层模块化架构,五层模块完全解耦,所有电路数据全部封装独立实体类,与前两版代码形成本质区别。
第一层:脚本解析层,独立处理文本逐行读取,区分主电路、Cx:子电路区块,拆分 INPUT、OUT、连线语句;
第二层:数据实体层,新增Circuit、Conn、EvalResult三大核心实体,单电路的输入、输出、连线全部封装在 Circuit 对象中,子电路通过全局subCircuits哈希映射隔离存储,不同层级电路状态互不干扰;新增Pin、SubPin实体,区分器件引脚、子电路端口两种信号格式,彻底解决前两版字符串判断混淆问题;
第三层:逻辑器件层,完全复用作业 5 Gate 所有子类,仅新增工具函数适配跨层端口电平读取,器件模块无需重构即可适配分层电路;
第四层:仿真求值层,新增递归evalCircuit()函数,实现子电路、顶层门分层求值,按子电路编号升序排序保证拓扑依赖顺序,彻底解决前两版单层循环无法处理嵌套电路的缺陷;
第五层:合法性校验层,新增validateCircuit()独立校验函数,通过生产者、消费者规则检测非法连线、信号多驱动冲突,提前抛出错误终止程序,弥补作业 4、5 无语法校验的短板。
作业 6 专属类图可直观体现相较前两版的巨大升级:完全消除全局静态数据耦合,实体类各司其职,单一职责清晰;支持无限层子电路嵌套拓展,新增器件无需改动仿真、解析核心逻辑;报错机制完善,可拦截大部分输入格式错误。短板是代码复杂度大幅提升,递归求值方法嵌套层级深,圈复杂度偏高,调试难度高于作业 4、5。
2.4 三份代码量化指标分开对比
通过三份独立 SourceMonitor 报表拆分数据,直观区分三套代码质量差异:
代码体量:作业 4 有效代码 426 行;作业 5782 行;作业 61247 行,体量逐级递增,拓展功能带来代码增量清晰;
重复代码占比:作业 4 31%,大量重复引脚解析逻辑;作业 5 17%,抽取基础工具函数优化;作业 6 9%,统一封装解析工具,复用性最优;
平均圈复杂度:作业 4 4.1(仅单层循环);作业 5 6.7(复合器件多层分支);作业 6 12.3(递归多层嵌套);
注释覆盖率:作业 4 11%,仅核心计算简单注释;作业 5 19%,补充复合器件引脚注释;作业 6 27%,递归、校验规则添加完整说明;
拓展能力:作业 4 仅支持 5 种单层基础门;作业 5 支持 9 种单层器件;作业 6 支持 9 种器件 + 无限层嵌套子电路。
2.5 三套代码运行流程分开梳理
作业 4 运行流程(单层极简版):读取文本→解析 INPUT 存入静态数组→解析连线填充门 pin 数组→单层 while 循环更新门输出→遍历所有门打印结果;全程无分层、无递归、无错误校验。
作业 5 运行流程(单层拓展版):继承作业 4 输入、连线解析逻辑→新增多路输出引脚填充逻辑→优化信号传播重置步骤→带迭代上限的单层仿真循环→区分单 / 多路输出打印;依旧仅支持单层电路,不支持子电路。
作业 6 运行流程(分层递归版):读取文本拆分主电路 + 全部子电路→全局校验所有连线合法性→初始化顶层外部输入电平→递归循环:子电路升序求值→顶层逻辑门求值→顶层端口更新→无电平变更终止→统一收集所有层级输出打印;新增子电路递归、语法校验两大核心流程,是前两版流程的完整升级重构。
三、采坑心得(分三份代码独立复盘)
3.1 作业 4 初代代码专属踩坑
所有 BUG 均为单层基础框架特有问题,后两版代码通过重构优化彻底规避:
Gate 父类静态数组初始化缺失:作业 4 仅声明pin[]数组,构造函数未循环赋值 - 1,Java 默认 0 与有效低电平混淆,门isValid()判定错乱,测试通过率仅 42%。该问题在作业 5、6 中统一在 Gate 构造函数完成全数组初始化,不再复现。感悟:初代代码仅追求功能实现,忽略数组自定义初始状态,拓展版本必须优先完善成员变量初始化逻辑。
全局连线数组无边界保护:作业 4lineEnd固定长度过小,测试用例连线目标过多直接数组越界崩溃;作业 5 适度扩大数组长度,作业 6 改用 List 动态集合彻底解决数组容量限制问题。
无信号冲突检测:作业 4 多条连线驱动同一引脚时电平随机覆盖,无任何报错;该缺陷在作业 6 新增from驱动映射表,提前拦截冲突,从根源解决。



3.2 作业 5 拓展版代码专属踩坑
BUG 仅出现在复合器件拓展阶段,作业 4 无相关逻辑,作业 6 通过封装寻址工具优化:
多路输出器件下标偏移计算失误:作业 5 新增译码器、分路器outMulti数组,读取端口时未叠加控制引脚偏移,直接使用端口数字当下标,出现越界、电平颠倒;作业 6 封装独立寻址函数统一计算偏移,消除手写下标失误。
环路电路死循环:作业 4 无迭代上限,测试反馈电路直接卡死;作业 5 新增 5000 次最大迭代常量解决,但仅适用于单层电路;作业 6 继承该限制,同时增加递归深度上限,适配嵌套环路场景。
复合器件判定分支冗长:作业 5 所有门类型判断全部在calcGate长 if-else 分支,新增器件必须修改核心计算函数;作业 6 虽复用该分支,但后续改进方案中提出工厂模式优化,弥补该缺陷。





3.3 作业 6 重构版代码专属踩坑
全部为分层、递归、子电路解析新增的独有 BUG,作业 4、5 不存在对应场景:
子电路 HashSet 无序遍历:作业 6 初代子电路存储使用无序集合,依赖底层子电路未优先求值,端口全部无电平;修复为按子电路编号升序排序遍历,前两版无嵌套电路不存在该问题。
两类信号解析优先级混乱:parsePin、parseSubPin判断无先后,C1-a同时匹配两种解析规则;作业 4、5 仅存在器件引脚,无该冲突,修复时设定先匹配子电路端口、再匹配器件引脚的优先级。
递归求值栈溢出风险:多层嵌套子电路时递归深度过大,程序崩溃;作业 4、5 无递归逻辑无需考虑,作业 6 新增递归深度阈值限制,拦截过度嵌套场景。
实体类数据传递污染:初期递归调用时直接共享全局电平 Map,子电路运算污染顶层信号;修复为每次递归创建独立子电路输入 Map,隔离层级状态,前两版全局数组天然存在数据污染隐患。



四、改进建议(分三份代码分别给出优化方向)
4.1 针对作业 4 初代基础代码优化建议
架构层面:舍弃全部全局静态数组,仿照作业 6 思路拆分Circuit、Conn实体类,解耦 Main 类存储与业务逻辑;
拓展层面:预留多路输出、控制引脚成员变量,提前改造 Gate 父类,避免后期拓展大规模重构;
健壮性层面:新增简单信号冲突校验逻辑,遍历连线时记录目标信号驱动源,重复驱动直接提示错误;
复用层面:抽取引脚拆分、数字判断工具函数,消除大量重复字符串处理代码,降低 31% 的重复代码占比。
4.2 针对作业 5 单层拓展代码优化建议
存储优化:将固定长度静态数组替换为动态 List 集合,彻底解决数组越界风险;
工具类拆分:将 Main 中所有静态解析、计算工具方法抽离独立 Tool 类,降低主类耦合度;
寻址逻辑封装:统一封装多路输出偏移计算函数,所有读取多输出引脚场景统一调用,消除手写下标错误;
校验补充:新增简易连线生产者、消费者校验,提前拦截驱动源位置颠倒、无输入输出等非法连线。
4.3 针对作业 6 分层重构代码优化建议
器件创建优化:替换if-else分支创建 Gate 子类的写法,引入工厂设计模式,新增器件仅需新增子类与工厂注册逻辑,无需修改核心调度代码;
状态语义优化:新增SignalState枚举替代 Integer 存储电平,区分未定义、0、1 三种状态,提升代码可读性;
异常体系优化:自定义解析、冲突、递归专用异常,携带错误行号、出错 token,替代单纯字符串错误提示;
仿真性能优化:增加变更器件缓存集合,每次迭代仅运算电平发生变化的器件,减少冗余循环遍历,降低递归运算耗时;
工程规范优化:为所有实体、工具方法补充完整 Javadoc 注释,统一变量命名规范,消除简写单字母变量。
五、总结
分开梳理作业 4、作业 5、作业 6 三套独立代码的完整开发过程,能够清晰看见本人编码能力、架构设计思维的分层提升。三套代码逐级迭代,从作业 4 极简全局耦合单层仿真,到作业 5 单层复合器件拓展,再到作业 6 分层递归模块化解释器,三套代码分别对应不同阶段的学习目标,各自存在独有的优势与无法回避的短板。
从三份代码独立收获来看,作业 4 让我熟练掌握 Java 抽象类、继承多态基础语法,理解数组存储业务状态的基础思路,但也暴露全局耦合架构的严重缺陷;作业 5 让我学会在原有代码基础上拓展新功能,掌握分支多类型逻辑处理、循环边界防护、基础代码复用优化,能够在不改动原有基础功能的前提下拓展复合器件;作业 6 让我彻底跳出全局静态编码思维,建立分层模块化工程设计思路,掌握自定义文本词法解析、递归分层求值、拓扑依赖排序、全局资源冲突校验等高阶逻辑,具备独立设计小型脚本解释器的能力。
分开审视三套代码暴露的分层短板:作业 4 短板集中在架构拓展性、代码复用性、程序健壮性,完全无异常校验、无分层设计,仅能完成极简需求;作业 5 短板为依旧依赖全局静态存储、工具方法耦合主类、缺少分层处理能力,仅适配单层电路;作业 6 短板集中在核心递归方法复杂度过高、缺少设计模式优化、性能存在冗余计算、工程注释规范不完善,虽功能完整,但代码可维护性、运行效率仍有提升空间。
结合三套代码各自缺陷,后续针对性学习规划也分层区分:针对作业 4、5 暴露的架构耦合问题,持续练习实体封装、分层解耦的代码设计;针对作业 6 暴露的复杂递归、高圈复杂度问题,练习嵌套逻辑拆分、算法简化技巧;同时系统学习设计模式,用工厂模式、单例模式优化器件创建、工具调用逻辑,补齐三套代码共同缺失的工程规范化短板。
本次分开复盘三份独立代码,完整对比三代仿真程序的设计、BUG、优化空间,清晰看清迭代过程中每一段代码的进步与不足,正视不同开发阶段自身编程思维的局限性,后续将针对三套代码暴露出的分层短板针对性练习,持续提升架构设计、代码优化、工程调试综合能力。

浙公网安备 33010602011771号