OOP4-OOP6题集总结与SourceMonitor分析报告
一、前言
经过前六次 Java 面向对象程序设计题集的学习与实践,我逐渐从最开始只会按照题目要求编写程序,转变为能够主动思考类之间关系、合理划分模块以及利用面向对象思想解决实际问题。回顾整个学习过程,六次题集的难度呈现出明显的递进趋势,题目规模不断扩大,功能需求也越来越复杂,对程序设计能力提出了更高要求。
从知识点来看,本阶段题集主要围绕面向对象程序设计展开,涉及类与对象、封装、组合关系、模块化设计、递归处理、数据结构以及数字逻辑模拟等多个方面。其中,前几次题集主要训练基础的面向对象思想,包括类的设计、对象之间的协作以及简单业务逻辑的实现;后续题集则逐渐增加系统复杂度,引入了子电路、逻辑门模拟、多种数字器件支持以及复杂数据管理等内容,使程序逐渐从简单的功能实现过渡到具有一定软件工程思想的小型系统开发。
从代码规模来看,随着题集不断迭代,程序的代码量也呈现出明显增长趋势。前期题集的类数量较少,代码结构相对简单,主要目标是理解面向对象编程的基本思想;而后期题集则开始强调模块化设计与复杂逻辑处理,代码规模明显扩大,类之间的关系也更加复杂。通过 SourceMonitor 软件生成的统计数据可以发现,程序的代码行数、语句数以及复杂度指标均有明显变化,这不仅体现了程序功能的增加,也反映出自己在程序设计能力方面的成长过程。
在整个学习过程中,我逐渐认识到,面向对象程序设计不仅仅是将代码写出来,更重要的是如何合理地进行类设计、如何降低模块之间的耦合度、如何提高程序的可维护性与可扩展性。特别是在后期题集中,当程序规模逐渐扩大时,一个合理的类结构往往比单纯实现功能更加重要。
因此,本篇博客将结合六次题集的实际完成情况,从题目分析、类图设计、SourceMonitor复杂度分析、程序开发过程中遇到的问题以及后续改进方向等多个方面,对本阶段学习情况进行系统总结,希望通过回顾与反思,进一步提升自己的程序设计能力,并为后续课程学习打下更加坚实的基础。
二、OOP题集4分析
(一)题目分析
OOP4题集主要围绕数字逻辑电路模拟展开,要求程序能够根据输入描述构建逻辑门电路,并完成信号传播和输出计算。相比前几次题集,本次作业已经不再是简单的数据管理,而是需要建立完整的数据模型,通过不同逻辑门之间的连接关系完成整个电路系统的模拟。
在程序设计过程中,我采用了面向对象的思想对系统进行建模。整个程序主要包含两个类,其中 Main 类作为程序入口,负责读取输入数据、控制程序整体运行流程以及输出结果;另一个核心类则负责逻辑门对象的描述,保存逻辑门类型、输入端口、输出状态等信息,并提供对应的计算方法。
在逻辑门设计方面,程序需要支持多种基本逻辑门,例如 AND 门、OR 门、NOT 门等。不同类型的逻辑门虽然输入输出规则不同,但都具有相似的数据结构,因此采用统一的数据结构进行管理,可以有效降低代码重复率,提高程序整体可维护性。
本次题目的重点在于信号传播过程的实现。程序需要根据门之间的连接关系,判断当前逻辑门的输入是否已经准备完成,然后按照逻辑门对应规则计算输出结果,并继续向后传播信号。因此,如何正确维护门之间的关系以及保证计算顺序的正确性,是本次题目的核心难点。
通过本次题集,我第一次接触到了数字逻辑模拟相关问题,也进一步体会到了面向对象建模的重要性。合理的类设计不仅能够简化程序逻辑,还能够为后续功能扩展提供良好的基础。
(二)类图分析

从类图可以看出,OOP4整体结构相对简单,主要由 Main 类和逻辑门类组成。
其中,Main 类负责程序整体流程控制,包括输入解析、对象创建以及结果输出;逻辑门类则负责保存逻辑门的状态信息以及执行逻辑运算。通过将业务逻辑封装到独立类中,程序避免了将所有代码集中在 main 方法中的问题,提高了代码可读性。
此外,逻辑门类中还封装了输入端口、输出状态以及计算函数,使每个对象都具有独立的状态与行为,这体现了面向对象程序设计中的封装思想。
整体来看,本次题集虽然类数量较少,但已经初步体现出模块化设计思想,为后续更复杂系统的实现奠定了基础。
(三)SourceMonitor分析

根据 SourceMonitor 软件统计结果,OOP4 项目总代码行数为252行,Statements数量为166,整体代码规模适中。
项目共包含2个类,说明程序整体结构相对简单,但已经开始体现类之间职责划分的思想。
从复杂度指标来看,项目最大复杂度(Max Complexity)达到15,平均复杂度(Avg Complexity)为6.00,说明程序中存在一定规模的条件判断与逻辑控制。其中,复杂度较高的方法主要集中在逻辑门计算以及输入解析部分,这是因为程序需要根据不同门类型执行不同运算规则。
此外,项目最大嵌套深度(Max Depth)为4,说明程序内部存在多层条件判断,但整体仍保持在可接受范围内。通过这些数据可以看出,本次题集已经开始从简单对象管理转向较复杂业务逻辑处理,程序结构也逐渐向真实软件系统靠近。
(四)踩坑心得
在完成 OOP4 的过程中,我遇到的最大问题是逻辑门之间信号传播顺序的处理。
最开始编写程序时,我采用的是“读取一个逻辑门立即计算输出”的方式。然而,当某个逻辑门的输入依赖于其他逻辑门输出时,这种方法会导致部分输入数据尚未准备完成,从而出现错误结果。经过调试后,我发现数字逻辑电路实际上具有明显的先后依赖关系,只有当前驱逻辑门完成计算后,后继逻辑门才能继续计算。
为了解决这一问题,我重新设计了程序流程,在计算之前先判断逻辑门所有输入端是否已经准备完成,只有满足条件时才执行逻辑运算。通过这种方式,程序成功解决了由于计算顺序错误导致的结果异常问题。
除此之外,我还遇到了逻辑门类型判断错误的问题。由于程序需要支持 AND、OR、NOT 等多种逻辑门,不同门的输入数量和运算规则都不相同,刚开始时我采用大量 if-else 语句进行判断,导致代码可读性较差,后期修改时也容易出错。后来,我将不同逻辑门的规则进行了统一封装,使程序结构更加清晰,代码维护难度也有所降低。
通过本次题集,我认识到程序设计不仅仅是实现功能,更重要的是合理组织程序结构。一个良好的设计方案往往能够减少后期调试工作,提高代码质量和开发效率。同时,我也意识到,在处理具有依赖关系的问题时,必须充分考虑数据流向和执行顺序,否则即使程序语法正确,也可能无法得到正确结果。
(五)改进建议
虽然 OOP4 已经完成了题目要求的功能,但从程序结构来看,仍然存在一些值得改进的地方。
首先,目前程序只包含两个类,并且大量业务逻辑集中在 Main 类中,导致 Main 类承担了过多职责。后续可以考虑将逻辑门、输入端口以及信号传播过程分别封装为独立类,使程序结构更加模块化,符合面向对象中的单一职责原则。
其次,在逻辑门类型判断方面,目前程序主要依赖条件语句进行区分。随着逻辑门种类不断增加,大量的条件判断会降低代码可读性,并增加维护成本。因此,可以考虑利用继承和多态思想,为每种逻辑门建立独立子类,通过重写计算方法实现不同逻辑门的逻辑运算,从而减少条件分支,提高程序扩展性。
另外,目前程序对于异常输入的处理还不够完善,例如非法逻辑门类型、输入数量不匹配等情况,可以增加专门的输入校验模块,对输入数据进行统一检查,提高程序鲁棒性。
总体来看,OOP4 虽然规模不大,但已经让我接触到了数字逻辑模拟和面向对象建模思想。未来如果继续优化,我会更加注重类职责划分、模块解耦以及程序扩展性设计,使程序不仅能够完成题目要求,也能够保持良好的代码质量和维护性。
三、OOP题集5分析
(一)题目分析
OOP5 是本阶段题集中难度提升最明显的一次作业。本次题目在 OOP4 数字逻辑门电路模拟的基础上,进一步增加了子电路(SubCircuit)的概念,要求程序不仅能够模拟普通逻辑门之间的连接关系,还需要支持子电路的定义、实例化以及递归展开。这使得程序从简单的逻辑门计算,逐渐发展成为一个具有层次结构的数字电路模拟系统。
在程序设计过程中,我仍然采用面向对象思想进行建模,将电路中的不同元素抽象为不同的数据结构。其中,Main 类负责程序整体运行流程,包括读取输入、保存电路信息、处理信号传播以及输出结果;此外,还设计了 SubCircuitDef 类用于描述子电路的定义信息,包括子电路名称、输入端口、输出端口以及内部连接关系。
与前一次题集相比,本次最大的变化在于子电路的引入。子电路本质上可以理解为一个已经封装好的功能模块,在主电路中可以被重复调用。因此,程序需要能够识别子电路实例,并递归地展开其内部结构,将子电路内部的逻辑门与外部连接关系统一管理。
为了实现这一功能,我使用 Map 结构保存信号、线路以及逻辑门之间的映射关系,通过 expand() 方法完成子电路递归展开,通过 processDst() 方法处理信号传递,通过 collectOutput() 方法统一收集输出结果。
由于系统中存在大量逻辑判断和数据映射关系,因此本次题集的代码复杂度明显增加。在编写过程中,需要同时考虑子电路展开顺序、信号正确传播以及异常情况处理等多个问题,对程序设计能力提出了更高要求。
总体来看,OOP5 已经不仅仅是简单功能实现,而是开始接触模块化设计与递归思想,通过对子电路进行抽象和封装,使程序整体结构更加接近真实软件系统。
(二)类图分析

从类图可以看出,OOP5 相比 OOP4 的系统结构明显更加复杂。
整个程序主要由 Main 类和 SubCircuitDef 类组成,其中 Main 类承担系统控制中心的作用,负责保存电路中的逻辑门、线路连接关系以及信号状态;SubCircuitDef 类则负责对子电路进行封装,保存子电路的输入输出端口以及内部连接信息。
Main 类中包含多个重要的数据结构,例如 signalMap、wireMap 和 gateReg 等。这些映射结构共同维护整个电路系统的运行状态。其中,signalMap 用于保存信号状态,wireMap 用于保存线路连接关系,gateReg 则用于保存逻辑门注册信息。
此外,Main 类还包含多个核心方法,包括 expand()、processDst()、collectOutput() 和 checkConn() 等。其中,expand() 方法负责对子电路进行递归展开,是整个系统实现模块化设计的重要组成部分;processDst() 方法负责信号传播;collectOutput() 方法用于收集最终输出结果;checkConn() 方法则负责检查线路连接是否合法。
通过将子电路抽象为独立对象,并利用递归方式展开,程序有效实现了模块复用,提高了代码的可扩展性。整体来看,OOP5 的类图结构已经具备明显的软件工程特征,体现了面向对象设计中的封装性和模块化思想。
(三)SourceMonitor分析

根据 SourceMonitor 软件生成的统计结果,OOP5 项目共包含 1 个 Java 文件,总代码行数达到 440 行,Statements 数量达到 340,代码规模相比前几次题集有明显增长。
虽然整个项目只有一个 Main.java 文件,但其中实际包含了 6 个类,说明程序已经采用了较为复杂的内部类设计方式,通过不同类完成不同功能模块的实现。
从复杂度指标来看,项目最大复杂度(Max Complexity)达到 37,是目前所有题集中最高的一次;平均复杂度(Avg Complexity)达到 8.83,也明显高于前几次题集。这说明程序中存在大量条件判断以及复杂逻辑控制。
此外,项目中的方法数量也明显增加。由于需要处理子电路展开、信号传播以及异常检测等多个功能,因此 Main 类承担了较多业务逻辑,导致部分方法规模较大,复杂度较高。
不过,从整体结构来看,虽然程序复杂度有所提高,但通过对子电路进行封装以及合理划分功能模块,程序仍然保持了较好的可读性。SourceMonitor 的统计结果也反映出,本次题集已经开始向复杂系统设计方向发展,对代码组织能力和模块化思想提出了更高要求。
(四)踩坑心得
在完成 OOP5 的过程中,我遇到的最大问题就是子电路的递归展开。
一开始,我尝试直接将子电路当作普通逻辑门进行处理,但很快发现这种方式无法正确维护子电路内部与外部之间的连接关系。当子电路嵌套层数增加时,信号传播顺序也会变得混乱,导致计算结果出现错误。
后来,我重新设计了数据结构,将子电路定义信息单独封装到 SubCircuitDef 类中,并通过 expand() 方法递归展开子电路。这样,程序在运行过程中会先将子电路转换为普通逻辑门结构,再统一进行信号传播和计算,从而保证了计算结果的正确性。
此外,我还遇到了线路连接错误的问题。由于线路数量较多,部分输入端和输出端可能出现重复连接或者非法连接,因此我增加了 checkConn() 方法,对线路进行合法性检查,及时发现错误输入。
通过这次题集,我深刻体会到,当程序规模不断扩大时,仅仅实现功能已经远远不够,更重要的是合理设计数据结构和模块之间的关系。一个优秀的数据结构设计,往往能够极大降低程序实现难度,提高代码质量。
(五)改进建议
虽然 OOP5 已经实现了题目要求的所有功能,但仍存在一定改进空间。
首先,目前程序虽然定义了多个内部类,但整体仍然集中在 Main.java 文件中,导致 Main 类承担了过多职责。后续可以考虑将 SubCircuitDef、信号管理模块以及线路管理模块拆分为独立文件,使程序结构更加清晰。
其次,部分方法复杂度较高,例如 expand() 和 processDst() 方法中包含较多条件判断,可以进一步拆分为多个小函数,降低单个方法复杂度,提高代码可读性。
此外,目前程序主要依赖 Map 保存各种映射关系,虽然实现简单,但数据结构之间耦合程度较高。后续可以通过增加专门的 Signal 类、Wire 类等对象,对数据进行进一步封装,使程序更加符合面向对象设计原则。
总体来看,OOP5 已经让我初步接触到了复杂系统设计思想,但在模块化、解耦以及代码组织方面仍有较大提升空间,这也是我后续学习过程中需要重点关注的问题。
三、OOP题集6分析
(一)题目分析
OOP6 是本阶段题集中综合性最强、系统结构最完整的一次作业。本次题目在 OOP5 的基础上进一步扩展,不仅需要支持普通逻辑门和子电路,还增加了多种复杂数字逻辑元件,例如三态门(TRISTATE)、译码器(DECODER)、多路选择器(MUX)以及多路分配器(DEMUX)等。相比前几次题集,本次作业已经从简单逻辑模拟逐渐发展为一个较为完整的数字逻辑电路模拟系统。
在程序设计过程中,我继续采用面向对象思想对系统进行建模。首先,通过枚举类型 ComponentType 对不同数字逻辑元件进行统一管理,包括 AND、OR、NOT、XOR、XNOR、TRISTATE、DECODER、MUX 和 DEMUX 等器件。这样既保证了代码结构统一,也方便后续扩展新的逻辑元件。
此外,我设计了 Component 类作为整个系统中的核心类,用于描述逻辑元件的基本属性,包括元件名称、元件类型、输入端口状态、输出状态以及计算标志等信息。通过将不同逻辑器件抽象为统一对象,程序能够采用统一方式完成信号输入、状态更新以及结果计算。
为了表示信号连接关系,程序中还设计了 Driver、InputPin 以及 Signal 等辅助类。其中 Driver 用于表示信号驱动端,InputPin 用于表示输入端口,而 Signal 则负责保存线路中的信号状态。通过这些类之间的协作,程序能够完整模拟数字电路中的信号传输过程。
本次题目的难点主要集中在复杂元件的实现以及多输出信号处理。例如,译码器和多路分配器具有多个输出端口,程序不仅需要正确计算输出结果,还需要保证信号能够按照正确线路传播。此外,三态门的输出状态不仅包括高电平和低电平,还需要考虑高阻态,因此需要额外设计状态判断逻辑。
总体来看,OOP6 不仅考察了面向对象程序设计能力,也涉及数字逻辑系统建模、复杂数据结构管理以及模块化设计等多个方面,是本阶段题集中综合性最强的一次实践。
(二)类图分析

从类图可以看出,OOP6 的系统结构相比前几次题集更加复杂,整体设计已经具备明显的软件工程思想。
其中,ComponentType 枚举类负责定义所有逻辑元件类型,包括基本逻辑门以及复杂数字器件。通过枚举统一管理元件类型,程序能够根据不同类型执行相应逻辑运算,提高代码可读性和扩展性。
Component 类是整个系统中的核心类,负责保存元件状态以及实现逻辑计算。该类中不仅包含输入输出信息,还封装了 evaluate()、isReady() 和 setInputValue() 等方法,用于完成元件状态判断和逻辑运算。
除此之外,程序还定义了 Driver、InputPin 和 Signal 等辅助类,用于描述信号驱动关系和线路连接关系。其中,Driver 类表示信号来源,InputPin 表示元件输入端,而 Signal 类负责保存信号状态。通过这些对象之间的协作,程序实现了数字电路中复杂的信号传播过程。
从整体结构来看,OOP6 已经形成了较为完整的对象体系,各个类之间职责明确、分工合理。相比 OOP4 和 OOP5,程序更加注重模块化设计和数据封装,体现了面向对象设计中高内聚、低耦合的思想。
此外,程序通过统一的 Component 类管理不同逻辑元件,也体现了抽象思想的优势。无论是普通逻辑门还是复杂数字器件,都能够采用统一接口进行管理,使系统具有较好的扩展能力。
(三)SourceMonitor分析

根据 SourceMonitor 软件统计结果,OOP6 项目共包含 1 个 Java 文件,总代码行数达到 419 行,Statements 数量达到 402,代码规模较大。
项目共包含 2 个类,虽然类数量相比 OOP5 有所减少,但程序内部采用了更加合理的数据结构和模块划分,使整体结构更加清晰。
从复杂度指标来看,项目最大复杂度(Max Complexity)为 6,平均复杂度(Avg Complexity)约为 3,明显低于 OOP5 的复杂度水平。这说明虽然 OOP6 的功能更加丰富,但由于程序结构进行了优化,复杂逻辑被有效拆分,降低了单个方法的复杂度,提高了代码整体可读性。
此外,项目最大嵌套深度(Max Depth)为 5,说明程序内部仍然存在一定规模的逻辑判断,但整体控制在合理范围内。通过这些统计数据可以发现,程序已经逐渐摆脱大量条件分支和复杂嵌套结构,而是通过对象封装和统一接口管理复杂业务逻辑。
总体来看,OOP6 的代码规模虽然较大,但复杂度控制较好,体现了良好的程序设计能力。从 SourceMonitor 的分析结果也能够看出,随着题集不断迭代,我对于类设计、模块划分以及复杂系统组织方式有了更加深入的理解。
(四)踩坑心得
在完成 OOP6 的过程中,我遇到的最大问题是复杂数字元件的统一建模。
最开始,我尝试为每一种逻辑元件单独编写计算代码,例如 AND 门、译码器、MUX 和 DEMUX 都分别设计不同的数据结构。这种方式虽然能够实现功能,但随着元件种类不断增加,代码量迅速膨胀,程序结构也变得越来越混乱。
后来,我重新思考程序设计方式,将所有元件统一抽象为 Component 类,通过 ComponentType 枚举区分不同元件类型。这样,程序只需要维护统一的数据结构,不同元件共享输入输出管理方式,只在逻辑计算部分进行区分,大大减少了重复代码,提高了程序可维护性。
此外,多输出元件的处理也是本次题集中的一个难点。例如译码器和 DEMUX 可能同时产生多个输出信号,如果输出管理不当,就容易出现信号覆盖或者输出错误的问题。为了解决这一问题,我重新设计了输出数据结构,使每个输出端口都能够独立保存状态,保证多个输出之间互不影响。
通过本次题集,我深刻认识到,当系统规模不断扩大时,良好的抽象能力和统一的数据结构设计往往比具体算法更加重要。合理的系统设计不仅能够降低开发难度,也能够提高代码质量和后续维护效率。
(五)改进建议
虽然 OOP6 已经实现了题目要求的全部功能,但从软件工程角度来看,仍然存在进一步优化空间。
首先,目前程序仍然采用单文件结构,虽然内部通过多个类完成模块划分,但随着功能继续增加,Main.java 文件规模会进一步扩大。因此,后续可以考虑将 Component、Signal、Driver 等类拆分为独立文件,进一步降低模块之间耦合度。
其次,目前不同逻辑元件的计算过程主要通过枚举类型进行区分。当元件数量继续增加时,大量条件判断会降低程序可读性。因此,可以考虑采用继承与多态思想,为不同元件设计独立子类,通过重写 evaluate() 方法实现各自逻辑运算,从而减少条件分支,提高程序扩展性。
此外,目前程序主要关注功能实现,对于异常输入以及边界情况处理还可以进一步加强。例如非法端口连接、重复信号驱动以及错误元件类型等情况,都可以增加专门的异常处理机制,提高程序健壮性。
总体来看,OOP6 是本阶段题集中最具挑战性的一次实践。通过本次题集,我不仅提升了面向对象程序设计能力,也进一步理解了复杂系统设计、抽象建模以及模块化开发的重要性。这些经验对于后续学习和软件开发实践都具有重要意义。
五、阶段学习总结
经过本阶段六次面向对象程序设计题集的学习与实践,我对 Java 面向对象程序设计有了更加系统和深入的理解。从最开始只能按照题目要求编写简单程序,到现在能够独立完成较复杂系统的设计与实现,我切实感受到了自己编程能力和软件设计思维的成长。
首先,在面向对象思想方面,我对“类”和“对象”的理解更加深刻。刚开始学习时,我更多关注的是程序能否运行以及功能是否实现,而忽略了程序结构设计的重要性。随着题集难度不断提升,我逐渐认识到,一个优秀的程序不仅需要正确实现功能,更需要具备清晰的结构、合理的类设计以及良好的可维护性。因此,在后续题目中,我开始主动思考类之间的关系,尝试利用封装思想将不同功能划分到不同类中,使程序结构更加清晰。
其次,通过六次题集的练习,我对面向对象中的封装思想有了更加直观的认识。在 OOP4 中,我开始尝试将逻辑门抽象为独立对象;在 OOP5 中,我进一步引入子电路概念,通过模块化设计实现复杂电路的递归展开;而在 OOP6 中,我又将各种数字逻辑元件统一抽象为 Component 类,并利用枚举对不同元件进行统一管理。这一过程让我意识到,优秀的软件设计往往建立在合理抽象和统一建模的基础之上。
此外,我对程序复杂度以及代码质量也有了新的认识。通过使用 SourceMonitor 软件分析代码,我第一次从数据角度观察自己的程序,例如代码行数、方法复杂度、嵌套层数以及类数量等指标。这些数据让我更加客观地认识到程序存在的问题。例如,当某个方法复杂度过高时,往往说明该方法承担了过多职责,需要进一步拆分;当 Main 类过于庞大时,则说明程序模块划分还不够合理。通过不断分析和优化,我逐渐养成了关注代码质量和程序结构的习惯。
当然,在学习过程中,我也发现了自身存在许多不足。首先,我在程序设计初期往往过于关注功能实现,而忽视整体架构设计,导致后期修改代码时工作量较大。其次,对于继承、多态等高级面向对象思想的应用还不够熟练,在处理复杂系统时,仍然容易出现代码耦合度较高的问题。此外,对于异常处理、设计模式以及软件工程方面的知识掌握还不够深入,这些都是我后续需要重点学习和提升的方向。
对于课程本身,我认为这种“题集逐步迭代”的教学方式非常有意义。通过不断在原有系统基础上增加新功能,能够让学生真正体验软件开发过程中需求变化和系统演进的过程,也能够培养学生持续优化和重构代码的能力。同时,配合 SourceMonitor 和 UML 类图分析,不仅能够锻炼编程能力,还能够帮助学生形成软件工程思维,提高代码质量意识。
总体而言,本阶段的学习让我不仅掌握了 Java 面向对象程序设计的基本知识,更重要的是培养了软件设计思维和问题分析能力。我相信,这些经验和收获不仅能够帮助我完成后续课程学习,也会对未来的软件开发实践产生积极影响。今后,我将继续加强面向对象设计、软件工程以及算法数据结构等方面的学习,不断提升自己的编程能力和综合素质,为今后的学习和工作打下更加坚实的基础。
浙公网安备 33010602011771号