前言
在完成 题目集 7 和 8 的过程中,我们进一步提升了对于物理系统模拟的理解,并掌握了更加复杂的面向对象编程技巧。这两次作业不仅在逻辑深度上更加复杂,还引入了更加丰富的设备类型与电路规则,对代码结构和算法提出了更高的要求。
- 家居强电电路模拟程序-3:
- 主要模拟串联与并联电路中的设备逻辑。
- 实现了开关、调速器、灯具、风扇等设备的基本状态计算,涵盖了串联与多路并联的复杂性。
- 家居强电电路模拟程序-4:
- 在前一版本基础上,加入了 互斥开关 和 二极管 等新设备,进一步完善了设备的物理特性模拟。
- 新增了电流限制和短路检测的功能,实现了更加严格的电路规则校验。
通过这两次题目,我们深入学习了如何运用 继承与多态 模拟不同设备的行为,如何设计具有扩展性的电路模型,并逐渐掌握了高效的调试与优化策略。
设计与分析
系统设计
本次题目以电路设备为核心,构建了一套基于 继承 和 组合 的强电电路模拟系统。系统主要包含以下模块:
- 设备模块:定义所有电路设备的通用属性和方法,如电压、电流、阻抗等。
- 控制设备:实现开关、调速器和互斥开关等设备的逻辑,负责调节电压和控制电路。
- 受控设备:实现灯具、风扇和窗帘的逻辑,根据输入电压计算状态(亮度、转速或开闭程度)。
- 电路模块:
- 串联电路:按顺序传递电压。
- 并联电路:实现电流分配和并联设备的逻辑。
- 主控模块:
- 负责输入解析、设备生成、电路连接及最终的模拟运行。
核心模块分析
1. 类图设计
classDiagram AbstractElectronic <|-- AbstractLight AbstractElectronic <|-- AbstractFan AbstractElectronic <|-- AbstractSwitch AbstractElectronic <|-- AbstractContinuousGovernor AbstractElectronic <|-- AbstractBinningGovernor AbstractElectronic <|-- Circuit AbstractElectronic <|-- SeriesCircuit AbstractElectronic <|-- CircuitDiagram AbstractLight <|-- Incandescent AbstractLight <|-- Fluorescent AbstractFan <|-- Fan AbstractFan <|-- FloorFan AbstractSwitch <|-- Switch AbstractContinuousGovernor <|-- ContinuousGovernor AbstractBinningGovernor <|-- BinningGovernor class AbstractElectronic { - String name - double voltage - double current - double resistance + renew() } class AbstractLight { - double brightness } class AbstractFan { - double speed } class Circuit { - List<AbstractElectronic> electronics } class SeriesCircuit { - List<AbstractElectronic> circuits } class CircuitDiagram { - List<AbstractElectronic> diagram } class Input { + String getInput() + int judgeInput() } class Controller { - CircuitDiagram circuitDiagram - Input input + void operation() + void showInfo() }2. 模块功能
控制设备:
- Switch:模拟开关的状态切换,0 状态断路,1 状态通路。
- ContinuousGovernor:支持连续调节的调速器,输入比例范围为 [0.00-1.00]。
- BinningGovernor:实现分档调速器的逻辑,支持四档调节。
- MutualSwitch(互斥开关):模拟二分状态,支持两种连接方式。
受控设备:
- 灯具:
- Incandescent:根据输入电压计算亮度,亮度在 [0-200 lux] 范围内线性变化。
- Fluorescent:两种状态,电压为 0 时亮度为 0,否则亮度恒定为 180 lux。
- 风扇:
- Fan:线性关系计算转速。
- FloorFan:分档计算转速。
- 窗帘:
- 根据所有灯光的亮度总和调整窗帘开合比例。
- 二极管:
- 根据电流方向判定导通或截止状态。
电路模块:
- SeriesCircuit:逐个设备传递电压,遇到阻断点停止传递。
- CircuitDiagram:整体管理电路拓扑结构,并计算各设备状态。
静态分析
SourceMonitor 报表分析:
-
代码规模与结构
代码行数 (Lines):1100 行,表明代码规模较大,逻辑实现较复杂,适合进行模块化设计和结构优化。
语句数 (Statements):458 条,反映代码中包含了较多逻辑处理过程,需关注核心逻辑的复杂度和效率。
类与接口数量:9 个类或接口,说明程序已采用面向对象编程思想进行设计,遵循模块化开发原则。 -
注释覆盖率分析
注释比例 (Percent Lines with Comments):11.9%,注释覆盖率较低。
注释不足可能影响代码的可读性和维护性,尤其对于复杂逻辑和嵌套代码块,建议增加详细注释,以便团队成员理解和维护代码。 -
复杂度分析
分支语句比例 (Branch Statements):22.1%,代码中包含较多条件分支(if-else、switch-case),逻辑分支较多,需关注条件判断的合理性及优化。
最大复杂度 (Maximum Complexity):3,虽然复杂度总体可控,但某些方法(例如 Main.main())仍存在复杂逻辑,可能需要拆分为多个子方法降低复杂度。
代码块深度分析:
最大代码块深度为 5,显示代码逻辑嵌套较深,可能导致理解困难和维护风险。
平均深度仅为 1.11,整体代码仍然保持一定的平坦结构,复杂逻辑集中在少量模块中。 -
模块设计与方法分析
方法数量与分布:平均每个类有 7.22 个方法,每个方法平均包含 6.86 条语句,表明代码方法粒度较为合理,大多数方法职责单一。
最复杂方法:Main.main() 方法位于第 7 行,被评为最复杂的方法。这表明主方法可能承担过多任务,违反单一职责原则,需要拆分逻辑。 -
图表分析
Kiviat Graph 图解:
显示复杂度、注释比例和嵌套深度略有失衡,注释比例偏低,复杂度部分超出合理范围,需优化设计与注释覆盖率。
Block Histogram 图解:
大部分代码块语句数较少(1~3 条),说明代码方法粒度较小,逻辑较为分散。
语句数超过 6 的代码块较少,但可能包含关键逻辑(如控制设备状态更新或电压计算),需重点关注这些代码块的优化与注释。 -
改进建议
注释优化:增加注释覆盖率,尤其是复杂逻辑和关键模块(如串联与并联电路的电压传递逻辑),提高代码的可读性和维护性。
代码复杂度降低:对 Main.main() 方法进行拆分,简化复杂逻辑,提升可维护性和扩展性。
深层嵌套代码块(最大深度 5)应拆分为子方法,以降低耦合度。
模块设计优化:针对重复逻辑(如电压传递和设备状态更新),进一步提取公共方法,减少代码冗余。
考虑使用设计模式(如责任链模式或策略模式)优化设备控制与状态更新逻辑。
复杂度控制:使用工具进一步分析热点模块,并对高复杂度代码进行重构,确保未来扩展时不会因复杂性导致维护困难。
核心逻辑展示
以下是电路逻辑的核心代码分析:
@Override
public void renew() {
this.setVoltage(this.getVBefore() - this.getVAfter());
double totalResistance = 0;
for (AbstractElectronic device : electronics) {
totalResistance += device.getResistance();
}
this.setResistance(totalResistance);
boolean isBlocked = false;
for (AbstractElectronic device : electronics) {
if (!isBlocked) {
device.setVBefore(this.getVBefore());
device.setV(this.getVoltage() * (device.getResistance() / this.getResistance()));
device.setVAfter(device.getVBefore() - device.getV());
device.renew();
if (device instanceof Switch && ((Switch) device).isOff()) {
isBlocked = true;
}
} else {
device.setVBefore(0);
device.setV(0);
device.setVAfter(0);
device.renew();
}
}
}
逻辑解读:
- 初始化电路电压与总阻抗。
- 按顺序遍历设备,若电压未阻断,依次更新输入电压、电压差及输出电压。
- 若设备为开关且处于断开状态,标记电压阻断,后续设备状态归零。
采坑心得
在完成 家居强电电路模拟程序 系列题目时,我们经历了多次调试和优化的过程,这不仅暴露了代码中的问题,也让我深刻认识到程序设计中的陷阱和改进的方向。以下是开发过程中遇到的一些典型问题及解决方案:
1. 输入解析问题
- 问题描述:
在初期开发中,输入解析模块对输入格式的约束不够严格。例如:- 串联电路和并联电路的信息中,输入引脚与设备的顺序不规范(如多余空格或换行)。
- 控制设备调节信息格式校验时,正则表达式未考虑特殊字符的干扰,导致程序无法正确识别输入。
- 解决方法:
- 针对输入格式重新设计了正则表达式,并加入了严格的格式化校验。
- 使用预处理机制,在正则解析前去除多余空格、换行和无效字符,确保输入规范性。
- 心得:
输入是整个程序的入口,必须进行严格的校验,否则后续逻辑会混乱且难以排查错误。
2. 设备状态更新的耦合性
- 问题描述:
在串联电路中,设备状态的更新依赖于上一个设备的输出电压。例如,开关断开后,所有后续设备的状态需要手动清零。初期设计中,状态更新和电压传递逻辑高度耦合,导致:- 难以扩展新的设备类型(如二极管、互斥开关)。
- 程序的测试和维护难度显著增加。
- 解决方法:
- 将设备状态的更新逻辑独立为单独的方法
renew()
,并在电路中以统一方式调用。 - 在状态更新时,优先检查上游设备的电压是否有效,避免手动干预设备状态。
- 将设备状态的更新逻辑独立为单独的方法
- 心得:
过度耦合的代码是调试的大敌,通过逻辑解耦,我们不仅减少了错误发生的概率,还为后续扩展打下了基础。
3. 电路短路检测的遗漏
- 问题描述:
在并联电路的开发中,初期没有很好地处理设备之间的短路问题。例如:- 并联电路中的支路可能出现同一设备的输入输出引脚直接相连,导致电流无穷大。
- 二极管的状态判断逻辑初期未严格区分正向导通与反向截止,部分情况下模拟结果不符合实际。
- 解决方法:
- 在并联与串联逻辑中加入短路检测功能:
- 检查电路是否存在设备引脚直接相连的情况。
- 若检测到短路情况,终止计算并输出错误提示
short circuit error
。
- 对二极管增加方向判断机制,严格按照物理规则模拟其导通与截止状态。
- 在并联与串联逻辑中加入短路检测功能:
- 心得:
短路检测是确保模拟正确性的关键,必须在电路拓扑构建完成后进行全局校验。对于复杂的设备特性(如二极管),需要充分理解其物理行为,避免因逻辑漏洞导致错误结果。
4. 电流限制的初期遗漏
- 问题描述:
本次迭代新增了电流限制功能,但在初期实现中,未正确考虑电流超过限制时设备的状态变化,导致:- 部分设备在超过电流限制后仍继续工作。
- 输出中未能正确提示
exceeding current limit error
。
- 解决方法:
- 在设备基类
AbstractElectronic
中增加maxCurrent
属性。 - 在状态更新逻辑中加入电流校验,若电流超过限制,将设备标记为过载状态,并输出错误提示。
- 为调试方便,添加了设备电流和电阻的调试日志,用于验证计算是否正确。
- 在设备基类
- 心得:
对设备的物理限制建模是电路模拟的重要部分。在代码实现时,要确保模型覆盖所有可能的异常情况,并在结果中给出明确提示。
5. 并联电路逻辑的复杂性
- 问题描述:
并联电路的引入增加了电路模拟的复杂性,尤其是:- 并联电路的输入电压需保持一致,但初期实现中未验证支路间电压是否统一,导致测试结果异常。
- 并联电路中包含嵌套并联时,支路电流分配计算逻辑出现混乱。
- 解决方法:
- 在并联电路构建阶段,统一设置所有支路的输入电压,确保一致性。
- 引入递归机制,支持并联电路的嵌套结构:
- 在每条支路中递归调用电压和电流计算逻辑。
- 汇总所有支路的电流,作为并联电路的总电流。
- 心得:
复杂的电路逻辑需要通过递归或迭代的方式逐步分解。对输入条件进行严格约束,是保证计算正确性的基础。
6. 窗帘状态与灯光亮度的关联
- 问题描述:
初期实现中,窗帘状态完全依赖电压高低,未能动态计算光照强度的总和。测试中,多个灯具组合的情况下,窗帘状态未能正确反映亮度变化。 - 解决方法:
- 为每个灯具增加光照强度的计算方法。
- 在电路总状态更新时,汇总所有灯具的亮度,计算窗帘的开合比例。
- 增加窗帘工作电压的校验,若电压不足 50V,则窗帘默认全开。
- 心得:
在复杂的状态关联中,确保每个环节的逻辑独立且正确,避免因一个设备的逻辑错误影响全局结果。
改进建议
-
代码结构优化:
- 将 串联电路与并联电路 统一抽象为 ElectricCircuit 接口,减少逻辑重复。
- 引入 责任链模式 管理电压与电流传递逻辑。
-
功能扩展:
- 加入电压过载保护机制,输出错误提示。
- 为设备状态增加历史记录,便于调试与回溯。
-
代码注释与文档化:
- 提高注释覆盖率,特别是核心逻辑部分。
- 为复杂类(如 CircuitDiagram)增加 UML 图与详细说明。
总结
这两次题目深入模拟了物理系统的复杂逻辑,让我们在继承与多态、模块化设计以及逻辑优化方面有了更多体会。通过不断调试与优化,我们不仅掌握了 电路逻辑模拟 的基本技能,还认识到抽象设计与代码解耦的重要性。希望未来能够在此基础上,进一步实现高效、可扩展的复杂系统开发。
学期总结
这一学期的 Java 面向对象程序设计课程 是一次充满挑战和收获的学习之旅。从最初的 Java 基础语法,到逐步掌握类与对象的设计,再到尝试实现复杂的功能模块,每一步都让我对编程逻辑和思维有了更深刻的认识。
在这门课程中,我收获了以下几点:
-
面向对象编程思想
通过大量的实践和案例,我深刻理解了 封装、继承、多态 的重要性。每当遇到复杂问题时,我开始学会从系统的视角去设计类的关系,而不仅仅是解决某个具体问题。特别是在实现电路模拟程序时,基于抽象类和接口的设计让我看到良好架构的重要性。 -
复杂逻辑的模块化处理
在完成多题型判分程序和电路模拟程序的过程中,我逐渐认识到模块化设计的优势。将功能划分为独立的模块(如输入解析模块、设备状态模块),不仅使代码结构更加清晰,也显著提高了代码的可维护性。 -
调试与优化能力
本学期的大部分编程任务都需要经过大量调试才能得到正确的结果。特别是在电路模拟程序的开发中,遇到了逻辑混乱、状态依赖等问题,通过一步步理清思路、调整代码,我的调试能力有了显著提升。 -
代码复用与扩展性
随着项目的迭代,我逐渐体会到如何设计可复用的代码结构。例如在电路模拟中,通过将设备特性抽象化,大幅减少了新增设备时的修改工作量。这种 设计模式 的运用,为未来的项目开发提供了宝贵经验。
这一学期的 Java 学习让我明白,编程不仅仅是一门技术,更是一种思维方式。以下是我最想表达的一些想法:
-
对编程的兴趣进一步加深
通过这一学期的学习,我从简单的代码实现中找到了成就感,也对编程的创造力产生了更大的兴趣。每当一个复杂的逻辑运行成功,我都感到非常满足。 -
感谢老师的耐心指导
在学习过程中,无论是课堂上还是课后遇到的难题,老师总是能用通俗易懂的方式为我们解答。特别是在调试和优化方面,老师给出的建议让我受益匪浅。 -
对未来的期待
学习 Java 面向对象编程只是一个开始,接下来我希望能学习更多关于框架和实际应用的知识,例如 Spring 框架和数据库整合。我相信这些技能会让我在以后的学习和工作中更加从容。
最后,我想对自己说一句:这一学期虽然有过焦虑和迷茫,但坚持和努力让我学到了很多。希望未来的学习中,我能继续保持对编程的热爱,不断挑战更高的目标,也希望自己的代码水平能越来越高,早日实现独立开发复杂项目的能力。
标签:逻辑,代码,BLOG,电路,电压,device,设备 From: https://www.cnblogs.com/yzjdblogs/p/18637612