Blog2

一、前言

本学期的Java面向对象程序设计课程中,我再一次完成了数字电路模拟程序的三次迭代作业,从基础逻辑门电路模拟,到组合电路元件扩展,再到子电路与异常处理功能的实现,三次作业的难度、代码规模与业务复杂度呈阶梯式上升。三次作业中,我经历了从勉强实现功能到设计合理的面向对象架构的全过程,多次因逻辑错误、架构缺陷、边界场景考虑不全而导致测试点不通过,也在一次次调试与重构中加深了对面向对象设计、迭代开发与工程化思维的理解。

本次总结博客,我将从三次作业的整体情况、设计与分析、采坑心得、改进建议与总结五个维度,完整复盘三次作业的开发过程,梳理每一次迭代的技术难点、踩坑经历与成长收获。

二、三次作业整体情况概述

(一)作业集4:

本次作业是整个系列的入门版本,核心目标是实现五种基础逻辑门的电路模拟,支持电路输入、信号连接、逻辑运算与结果输出。

核心知识点:Java基础语法、面向对象基础(类与对象、继承、抽象类)、集合框架(HashMap、ArrayList)、简单的拓扑信号传播逻辑。

题量与难度:1道编程题,基础逻辑门场景简单,仅需处理信号传递与基础门运算,难度较低。

代码规模:约250行代码,包含1个主类、1个抽象门类、5个具体门实现类、2个工具类。

(二)作业集5:

本次作业在作业集4的基础上进行了全面升级,新增三态门、译码器、数据选择器、数据分配器四种组合电路元件,同时引入控制引脚、特殊输出格式、高阻态等概念,业务逻辑复杂度大幅提升。

核心知识点:面向对象继承与多态的深入应用、多类型引脚的管理、复杂信号计算逻辑、特殊输出格式处理、边界场景与高阻态的模拟。

题量与难度:1道编程题,新增元件逻辑复杂,需要处理控制信号有效性、译码器的编码转换、数据选择/分配的多路信号处理,难度中等偏上。

代码规模:约700行代码,在作业集1的基础上新增4个元件类,扩展了电路管理类的逻辑,引入电平常量类统一管理信号状态。

(三)作业集6:

本次作业在作业集4的基础上,新增了子电路嵌套与异常输入检测两大核心功能,同时需要兼容基础逻辑门的所有功能,对架构设计、错误处理能力提出了极高要求。

核心知识点:组合模式的应用、子电路的嵌套与信号交互、复杂输入解析、异常检测与优先级处理、多迭代的信号传播逻辑、输出格式规范。

题量与难度:1道编程题,子电路嵌套逻辑复杂,异常场景多且有优先级要求,需要同时处理主电路与子电路的信号传播,难度较高。

代码规模:约650行代码,新增子电路管理类、异常解析逻辑,重构了信号传播与输出打印逻辑,兼容基础逻辑门与子电路场景。

三、作业集 4:基础逻辑门电路模拟程序

(一)需求回顾

本次作业的核心需求是实现五种基础逻辑门的电路模拟,支持以下核心功能:

解析电路输入、元件定义与引脚连接信息;

实现与门、或门、非门、异或门、同或门的逻辑运算;

按照规定顺序(与门→或门→非门→异或门→同或门,同类按编号从小到大)输出元件的有效输出;

自动忽略输入不全、无法计算的元件。

(二)类设计与架构

本次作业采用了“抽象父类+具体实现类”的继承架构,通过抽象类Gate定义门电路的通用行为,不同逻辑门继承该抽象类并实现专属的运算逻辑,同时使用SignalBox统一管理所有引脚的信号状态,实现信号的全局传递。

核心类结构:

SignalBox:信号管理工具类,使用HashMap存储所有引脚的信号状态,提供信号的存、取、查询方法,作为全局信号的共享容器。

Gate:抽象门电路类,定义了门电路的通用属性(名称、输入引脚列表、输出引脚、输入数量)与通用方法(添加输入引脚、检查是否可运行、抽象运算方法run()、获取输出引脚与编号)。

And/Or/Not/Xor/Xnor:具体门电路类,继承Gate抽象类,实现各自的逻辑运算方法run()。

Circuit:电路管理类,负责元件的创建、连接解析、信号传播与结果输出,同时包含元件编号排序逻辑。

Main:主程序类,负责输入解析、电路初始化、模拟运行与结果打印。

(三)类图

(四)复杂度分析

四、作业集5:组合电路元件扩展模拟程

(一)需求回顾

本次作业在作业集4的基础上,新增了四种组合电路元件与控制引脚、特殊输出格式、高阻态等需求,核心新增功能如下:

新增三态门、译码器、数据选择器、数据分配器四种元件;

元件引脚按“控制-输入-输出”顺序排序;

三态门控制端为低电平时,输出为无效状态,不输出结果;

译码器仅输出为0的引脚编号,格式为元件名:编号;

数据分配器按引脚顺序输出信号,无效状态输出-;

输出顺序调整为:与门→或门→非门→异或门→同或门→三态门→译码器→数据选择器→数据分配器,同类按编号从小到大排序。

(二)类设计与架构改进

本次作业在作业集1的基础上,重构了架构,将每种元件独立为一个类,引入了LevelConstant常量类统一管理信号状态,新增CircuitManager类统一管理所有元件、信号与连接,同时使用InputParser类专门处理输入解析,提升代码的可维护性。

核心类结构改进:

新增LevelConstant:定义信号状态常量,提升可读性;

新增TriStateGate/Decoder/Multiplexer/Demultiplexer:四种新元件的实现类,各自实现专属的运算逻辑;

重构CircuitManager:替代原Circuit类,新增多类元件的管理列表、信号映射、连接映射与元件创建逻辑;

新增InputParser:将输入解析逻辑从主类中抽离,专门处理INPUT、连接行的解析,代码职责更清晰;

原Gate抽象类被拆分为独立的元件类,每个元件类实现compute()方法计算输出状态,printOutput()方法处理输出。

(三)类图

(四)复杂度分析

五、作业集6:子电路与异常处理增强模拟程序

(一)需求回顾

本次作业在作业集4的基础上,新增了子电路嵌套与异常输入检测两大核心功能,同时兼容基础逻辑门的所有功能,核心新增需求如下:

支持子电路定义与主电路引用,子电路可以嵌套定义,元件输出时需带上子电路编号;

子电路包含INPUT、OUT定义,子电路的输入/输出可作为主电路的引脚引用;

新增五种异常输入检测,按优先级输出最高级别的异常信息:

连接信息包含多个输入;

连接信息无输入;

连接信息无输出;

连接信息输入输出顺序写反;

输入引脚被多个输出信号驱动;

主电路与子电路的元件编号可重复,输出时按子电路编号+元件类型+编号排序。

(二)类设计与架构重构

本次作业采用了组合模式的思想,将主电路与子电路抽象为统一的电路单元,重构了整体架构,新增了Sub类管理子电路的输入、输出、元件与连接,同时新增异常解析逻辑,处理输入中的异常场景。

核心类结构:

Gate抽象类:保留作业集4的设计,定义门电路的通用属性与运算逻辑;

And/Or/Not/Xor/Xnor:基础逻辑门实现类,继承Gate抽象类;

Sub:子电路管理类,包含子电路的输入列表、输出列表、元件映射、连接映射与信号状态映射;

主程序类Main:负责输入解析、异常检测、信号传播与结果输出。

(三)类图

(四)复杂度分析

六、调试过程与采坑心得

(一)作业集4调试与踩坑

代码版本1

状态:非零返回

分数:0 / 100

报错点:所有测试点均非零返回,多层级联电路(case38~40)直接答案错误

核心问题:

splitBySpace方法错误:处理输入时逻辑错误,导致解析出的引脚数据混乱,无法正确创建元件。

信号传播逻辑缺陷:spreadSignal方法无法在级联电路中正确传递信号,导致后级门电路永远无法收到输入。

引脚管理混乱:findPin和addPin的设计无法处理跨元件的信号传递,allPins数组无法正确存储所有引脚。

代码版本2

状态:部分正确

分数:82 / 100

报错点:

case14:门级联组合 - 简单(答案错误)

case21~22、30:复杂连接(答案错误)

case35:边界与特殊组合(答案错误)

case37:多层级联电路(答案错误)

核心问题:

calcGroup的信号更新逻辑不完整:门电路计算后,输出信号没有被同步到SignalStore。

信号传播循环过早终止:spreadSignal只做了一次 BFS,没有处理多级级联的迭代传播。

多输入冲突处理缺失:没有检查同一引脚被多个源驱动的情况,导致冲突信号无法正确处理。

(二)作业集5调试与踩坑

代码版本1

状态:编译错误

分数:0 / 100

报错信息:Main.java:264: error: illegal character: '\uff1b'

报错原因:Selector类中outIndex;的分号是中文全角符号,导致编译失败。

代码版本2

状态:编译错误

分数:0 / 100

报错信息:Main.java:390: error: cannot find symbol outArr[pos]=""+result;

报错原因:Distributor类中使用了未定义的变量pos,正确应为position。

代码版本3

状态:部分正确

分数:82 / 100

报错点:

case8:简单电路测试(答案错误)

case20、25~26:元件组合 / 复杂电路(答案错误)

case34:基础元件测试(答案错误)

核心问题:

Decoder输出逻辑错误:译码器的输出信号没有被正确写入pinSignalMap,导致输出无法被后续电路读取。

Demultiplexer的信号清除逻辑问题:无效输出引脚的信号没有被移除,导致后续电路读取到错误的旧值。

元件排序逻辑不严谨:部分元件的getSerialNumber方法无法正确提取编号,导致输出顺序错误。

(三)作业集6调试与踩坑

代码版本1

状态:编译错误

分数:0 / 100

报错信息:Main.java:597: error: class, interface, enum, or record expected

报错原因:代码存在方法重复定义,且方法体没有被包含在类中,导致语法结构错误。

代码版本2

状态:部分正确

分数:91 / 100

报错点:

case8、24、29、41:多子电路/单子电路/单个异常(答案错误)

核心问题:

子电路内部信号同步不完整:subInnerSpread方法的迭代次数限制不足以处理深层嵌套的子电路,导致部分信号未完成传播。

子电路输出到主电路的同步时机错误:syncSubToMain没有在每次子电路迭代后立即同步输出,导致主电路读取到旧值。

多子电路优先级处理缺陷:多个子电路之间的信号传递没有按拓扑顺序处理,导致跨子电路的级联信号无法正确传递。

异常处理逻辑边界问题:case41的单个异常场景中,冲突检测逻辑无法识别子电路输出引脚的冲突。

七、改进建议与优化方案

(一)作业集4代码优化建议

信号传播优化:当前的信号传播采用无差别循环迭代,效率较低,可以采用拓扑排序的方式,减少迭代次数;

异常处理优化:当前代码对输入错误的处理能力较弱,可以添加简单的输入校验,提升程序的健壮性。

(二)作业集5代码优化建议

代码复用优化:四种新元件的类中存在大量重复的信号读取、输出判断逻辑,可以将通用逻辑抽离到父类中,减少代码冗余;

译码器逻辑优化:当前译码器的控制引脚与输入引脚的判断逻辑分散在代码中,可以将控制逻辑封装为单独的方法,提升代码的可维护性。

(三)作业集6代码优化建议

组合模式完善:当前主电路与子电路的管理逻辑较为分散,可以进一步完善组合模式,将主电路也抽象为电路单元,统一处理主电路与子电路的信号传播;

信号传播效率优化:当前主电路与子电路的信号传播都采用循环迭代,效率较低,可以为子电路添加依赖关系分析,按依赖顺序执行运算,减少迭代次数。

八、学习收获与总结

(一)三次作业的学习收获

面向对象设计能力提升:从作业集4的基础继承架构,到作业集5的独立类设计,再到作业集6的组合模式应用,我逐步理解了面向对象的核心思想,学会了根据业务需求设计合理的类结构,提升了代码的可维护性与可扩展性;

调试与排错能力提升:三次作业中,我遇到了编译错误、逻辑错误、边界场景错误、异常优先级错误等多种问题,通过打印日志、分步调试、对照样例核对等方式,逐步掌握了定位与修复错误的方法;

工程化思维提升:通过三次迭代作业,我理解了迭代开发的意义,学会了在原有代码的基础上进行扩展,而不是每次都重写,同时也意识到了代码规范、注释、架构设计对后续维护的重要性。

(二)存在的不足与后续学习计划

架构设计能力不足:作业集5与作业集6的代码架构仍存在冗余,部分模块的职责划分不够清晰,后续需要学习设计模式的应用,提升架构设计能力;

代码复用性不足:三次作业的代码中存在大量重复逻辑,如信号读取、输出打印、元件排序等,后续需要学习如何通过抽象类、接口、工具类减少代码冗余;

后续学习计划:

深入学习设计模式,尤其是组合模式、工厂模式在电路模拟这类场景中的应用;

练习编写高复用、低冗余的代码,提升代码的可维护性;

学习Java的异常处理机制,完善程序的错误处理能力;

尝试实现时序电路元件,进一步拓展数字电路模拟程序的功能。

九、结语

三次数字电路模拟程序作业,是我从Java基础语法到面向对象设计、再到工程化思维的成长过程。从最初只能勉强实现基础逻辑门的运算,到能够处理组合电路、子电路嵌套与异常场景,我不仅掌握了Java的核心知识点,更理解了软件开发不是一次性的编码,而是一个迭代、重构、优化的过程。

在今后的学习中,我会继续保持严谨的态度,正视代码中的不足,从架构设计、代码复用、异常处理等方面不断提升自己的编程能力,同时也会将本次作业中学习到的迭代开发思想应用到后续的课程学习与项目实践中,逐步成长为一名具备工程化思维的开发者。

posted @ 2026-06-24 22:29  董志凡  阅读(5)  评论(0)    收藏  举报