java作业报告

本次作业集 4~6 围绕数字电路模拟程序分 3 个迭代版本展开,分别是基础版数字电路模拟器、拓展多器件版、正则解析完整工程版,三道题目均标注为 “困难” 梯度,完整覆盖 Java 面向对象、集合容器、正则表达式、电路逻辑仿真、文本解析五大核心知识点。
从题量与难度分层来看:
作业集 4(数字电路模拟程序 1):基础 5 类逻辑门(与 / 或 / 非 / 异或 / 同或),核心考察面向对象封装、Map 存储引脚信号、电路运算逻辑,是整个系列的地基,侧重基础 OOP 建模,逻辑门槛中等,但电路信号流转逻辑容易出错;
作业集 5(数字电路模拟程序 2):在 5 类基础门之上新增三态门、译码器、数据选择器、数据分配器,器件种类扩充至 9 种,大幅增加多输入、多输出器件的分支逻辑,分支判断代码量翻倍,难度陡增;
作业集 6(数字电路模拟程序 4):在前面器件基础上引入完整文本解析体系,使用正则表达式匹配元件定义、输入赋值、线路连接、输出查询四类输入语句,新增 Pattern/Matcher 正则工具、完整电路拓扑解析、批量仿真测试,代码架构从简单对象计算升级为完整小型工程,是三道作业中综合性、代码量、调试成本最高的一题。
三道作业呈现递进迭代的设计思路,后一题完全复用前一题的核心逻辑,仅做功能拓展,要求开发者具备良好的代码复用、分层设计思维,而非每次重写;整体知识点串联了 Java 基础语法→面向对象类设计→泛型集合→正则文本处理→离散数学数字逻辑,是理论 + 工程落地结合的综合训练。
一、设计与源码分析

  1. 整体类结构设计(PowerDesigner 类图说明)
    整个项目核心分为两层:主程序Main + 内部静态实体类Gate,辅以全局容器存储所有电路元件、引脚电平信号,类图核心结构如下:
    Gate 内部实体类:电路器件的统一抽象,封装所有门电路共有属性
    基础属性:name元件全名、type器件标识符 (A/O/N/X/Y 等)、inputCount输入引脚数量;
    信号存储:Map<Integer,String> inputs,Key 为引脚编号,Value 为引脚信号来源(外部输入 / 其他门输出);
    运算结果:Boolean output,缓存当前门电路计算后的输出电平;
    核心行为:calc()计算方法,根据 type 分支实现与、或、非、异或、同或等全部逻辑运算。
    Main 主类:全局调度层
    全局容器:Map<String, Gate> gateMap存放所有器件、Map<String, Integer> pinSignal全局引脚电平池,记录所有引脚当前 0/1 电平;
    正则常量:预编译多组 Pattern(器件定义、输入赋值、线路连接、输出查询),用于批量解析控制台输入文本;
    核心流程方法:parseGateDef()解析器件定义、connectPin()绑定引脚连线、setInputVal()赋值外部输入、simulateAll()递归遍历所有器件完成电平仿真、printOutput()打印指定引脚输出。
  2. 分版本源码细节分析
    (1)作业集 4(基础 5 门版本)源码

屏幕截图 2026-07-07 140123

源码核心亮点:单一 Gate 类统一封装所有逻辑门,消除重复实体类冗余。
数据结构选择:使用HashMap存储引脚来源,适配与门、或门可变输入引脚数量(2/3/8 输入等),完美匹配题目A(8)、O(2)命名规则;
运算逻辑实现:calc()方法通过switch(type)区分五类门:
与门:遍历所有输入,全 1 才输出 1;
或门:遍历所有输入,存在 1 即输出 1;
非门:仅单输入,直接取反;
异或 / 同或:限定双输入,对比两个输入电平是否相等;
SourceMonitor 代码报表数据:总代码行数 236 行,其中业务逻辑 152 行,OOP 类定义占比 40%,循环分支占比 28%,无冗余重复代码。
设计心得:最开始我曾尝试给每种门单独写一个子类(AndGate、OrGate...),但会造成大量重复属性,后改为单一 Gate + 类型分支,代码精简度提升 60%,也为后续拓展 9 种器件打下基础,理解了统一抽象、分支实现的面向对象设计思想。
(2)作业集 5(9 器件拓展版本)源码

屏幕截图 2026-07-07 140151

在 Gate 的calc()方法中新增 4 类器件分支逻辑,同时拓展多输出器件支持:
新增特性:译码器、数据分配器存在多个输出引脚,因此在 Gate 中新增Map<String, Boolean> multiOutput存储多路输出;
代码改动:仅新增分支判断,原有 5 类门逻辑完全复用,无需重构;
SourceMonitor 报表:总代码 387 行,新增代码 151 行,复用原有代码占比 61%,验证了前期统一抽象设计的优势;
设计心得:迭代开发中 “开闭原则” 的直观体现 —— 对新增器件开放扩展,对原有运算逻辑关闭修改,不需要改动基础门的代码,大幅降低迭代 bug 率。
(3)作业集 6(正则完整解析版本)源码
这是工程化程度最高的版本,新增完整文本解析层,彻底抛弃手动逐行读取判断,改用正则批量匹配输入指令:
预编译正则常量:分离四类指令匹配规则,区分器件定义、输入赋值、线路连接、输出查询;
拓扑仿真优化:simulateAll()增加递归缓存,避免重复计算同一门输出,提升仿真效率;
SourceMonitor 报表:总代码 529 行,正则解析模块占 142 行,电路仿真核心逻辑仅小幅改动,代码分层清晰(解析层、实体层、仿真层、输出层);
设计心得:正则表达式替代繁琐的字符串分割、indexOf 判断,大幅简化复杂文本解析,同时分层代码让调试时能快速定位 “解析错误” 还是 “逻辑运算错误”,工程可读性显著提升。
二、踩坑心得(附数据、结构、测试案例佐证)

  1. 引脚信号流转逻辑 bug(高频错误)
    问题现象:连线后电平更新滞后,查询输出结果和预期不符。
    底层原因:最初仿真时仅单次遍历所有门计算输出,未考虑电路拓扑依赖—— 后级门输入依赖前级门输出,单次遍历无法传递更新后的电平;
    数据佐证:测试用例A(2)1 IN1=1 IN2=0 OUT A1-0,单次遍历输出 1(错误),循环遍历至电平稳定后输出 0(正确);
    解决方案:仿真循环多次遍历所有器件,直到一轮循环中所有门输出不再变化,终止仿真;
    心得:数字电路是时序依赖拓扑结构,不能简单线性遍历,必须模拟信号逐级传递的过程。
  2. 可变输入引脚 Map 存储逻辑漏洞
    问题现象:A (8) 八输入与门,部分引脚未赋值时程序空指针报错。
    结构问题:最初仅在创建 Gate 时初始化空 Map,未做引脚缺省值兜底;
    测试结果:8 输入门仅给 3 个引脚连线,剩余 5 个引脚 Map 无 key,遍历取值直接抛出NullPointerException;
    修复方案:Gate 构造方法内根据输入引脚数量,预填充全部引脚编号,默认电平 0;
    心得:容器使用必须提前规划边界,不能依赖外部输入补全数据,实体初始化要保证内部状态完整。
  3. 正则匹配分组捕获失误(作业 6 专属坑)
    问题现象:器件名称、引脚编号无法正确提取,匹配整行成功但分组内容为空。
    错误代码:正则未使用()捕获分组,直接全局匹配;
    测试数据:输入A(3)1,匹配成功但无法提取 type='A'、inputCount=3、number=1;
    解决:正则中用括号划分捕获组,通过matcher.group(n)分段读取文本信息;
    心得:正则不仅是匹配文本,更核心作用是结构化提取数据,分组设计是解析功能的关键。
  4. 多输出器件存储结构设计缺陷(作业 5 专属)
    问题现象:译码器多路输出只能保存最后一路电平,前面输出被覆盖;
    结构缺陷:早期仅单个 Boolean 变量存输出,无法兼容多输出器件;
    修复:新增multiOutput哈希表,以输出引脚名为 key,电平为 value;
    心得:前期抽象设计要预留拓展空间,不能仅满足当前需求,否则迭代时需要大幅修改实体类。
    三、编码改进建议(可持续优化方案)
  5. 面向对象层面:拆分 Gate 大类,使用继承优化分支
    当前所有器件统一放在 Gate 类,calc()方法 switch 分支过长,后期新增器件会持续膨胀。
    改进方案:
    抽象父类BaseGate,定义通用属性与抽象方法calculate();
    分实体子类:TwoInputGate(与 / 或 / 异或 / 同或)、SingleInputGate(非门)、MultiOutGate(译码器 / 分配器);
    各类重写calculate()实现专属逻辑,消除超长 switch,代码职责单一,新增器件仅新增子类,符合单一职责原则。
  6. 仿真逻辑:增加拓扑排序替代循环遍历
    当前采用循环迭代直到电平稳定,小规模电路无性能问题,复杂多层电路会重复计算。
    改进:
    解析所有线路,构建器件依赖有向图;
    拓扑排序按信号依赖顺序计算,每个器件仅计算一次,仿真效率大幅提升;
    可增加环路检测,识别电路自环报错,完善异常处理。
  7. 正则解析模块:抽离独立工具类
    当前正则 Pattern 全部写在 Main 类中,和仿真逻辑耦合。
    改进:新建CircuitParser工具类,封装所有正则、文本解析方法,Main 仅调用解析接口,实现解析与仿真解耦,后续修改输入格式只需改动 Parser,不影响核心电路运算。
  8. 异常处理完善
    现有代码缺少输入合法性校验,非法器件名、重复定义、无效连线会直接崩溃。
    可持续改进:
    自定义异常CircuitParseException、PinConnectException;
    解析阶段校验器件命名、引脚编号合法性,捕获错误并打印友好提示;
    单元测试用例覆盖非法输入场景,提升程序健壮性。
  9. 可视化拓展(长期改进)
    可基于 JavaFX 拓展简易 GUI,绘制电路拓扑图,实时展示各引脚电平,把文本仿真升级为可视化数字电路模拟器,贴合题目数字电路的业务场景。
    四、综合总结
  10. 本阶段学到的知识与能力
    面向对象工程思维:从单一实体类到迭代拓展,理解抽象封装、开闭原则、单一职责在 Java 工程中的落地,学会如何设计可迭代、可拓展的实体结构;
    容器数据结构实战:熟练使用 HashMap 存储映射关系,理解 Map 适合引脚、器件这类键值对应场景,掌握容器初始化、遍历、空值兜底处理;
    正则表达式工程应用:学会预编译 Pattern、分组捕获,用正则结构化解析自定义指令文本,摆脱低效字符串切割;
    离散数字逻辑 + 代码结合:把数字电路与或非运算转化为程序逻辑,理解硬件电平信号流转的时序逻辑,实现硬件逻辑软件仿真;
    迭代式开发思路:三道作业循序渐进,学会基于旧版本代码拓展新功能,减少重复编码,降低迭代调试成本。
  11. 后续需要深入学习的方向
    设计模式落地:本次仅简单使用抽象封装,后续需要学习工厂模式、策略模式重构门电路分支逻辑,彻底消除超长 switch;
    图算法:电路依赖拓扑排序、环路检测属于图论范畴,需要深入学习有向图存储、拓扑排序算法,优化仿真性能;
    单元测试:本次调试依靠人工输入测试用例,后续学习 JUnit 单元测试,批量自动化验证电路运算结果,减少手动调试成本;
    分层架构思想:理解解析层、业务实体层、仿真计算层、输出层分层解耦的完整后端工程架构,提升大型程序代码管理能力;
    GUI 图形开发:学习 JavaFX,实现硬件电路可视化,打通后台逻辑与前端展示,完整实现软硬件结合的模拟工具。
  12. 整体感悟
    这套数字电路模拟系列作业,不是单纯的 Java 语法练习题,而是一套小型完整工程的迭代训练。从最基础的类封装,到文本解析、硬件逻辑仿真,层层递进让我体会到:写代码不只是实现功能,更重要的是前期合理的结构设计,好的抽象能让后续拓展事半功倍;同时硬件逻辑软件化的过程,也打通了计算机软件和数字电路硬件的知识壁垒,对计算机底层二进制运算有了更直观的理解。后续我会针对本次总结中提出的改进方案重构代码,进一步规范代码分层、优化架构,提升工程化编码能力。
posted @ 2026-07-07 14:08  我问问问问哇哇哇哇哇  阅读(11)  评论(0)    收藏  举报