一.题目集七,7-1 家居强电电路模拟程序-3
1.前言
知识点考查和难度:
本题在上次迭代基础上增加了互斥开关和受控窗帘,以及电路的多并联。主要难度体现在互斥开关的引脚问题和通断特性。
更综合考查对设备的开关理解,和电路的逻辑结构。以及对电路设备的建立方式有些许的不同,加强了设备间的交互性。
2.设计分析
由于互斥开关相较于前几次的控制设备来说,互斥开关特点在于它有两个引脚用来控制两条分路。切换状态时不仅要切换原有闭合的电路中状态,还要切换另一个引脚的通路。为此,我设计互斥开关类有自己的独立引脚。对互斥开关设备的建立也做了独特的处理。检测建立时的引脚,并通过引脚区分互斥开关设备。然后也可以根据是否切换状态,来匹配建立时的引脚达到控制分路通断的作用。
受控窗帘部分,受控窗帘作为受控设备来说,它与灯设备有了交互。它受光照的影响来控制窗帘的开放。为此,我设计受控窗帘前需要在电路中新增计算总亮度的函数。在设备列表中查询灯设备的建立,并获取灯设备的状态。随后得到总亮度。受控窗帘更新状态时则需要获取计算的总亮度,根据不同的亮度挡位得到不同的开放量。
并联电路里有串联电路这个迭代点则需要我们在创建并联电路设备时向里面添加串联电路设备。与之前代码的逻辑结构大体相同,所以并没有做过多的设计修改。
总类图如下:
该程序的时序图如下:
3.踩坑心得
在计算受控窗帘的设备状态时总是得到错误的计算结果。
于是我从设备的电压开始检验。用简单的串联电路进行测试。发现并没有问题。电压没有问题,于是考虑光照,经过计算光照结果,发现是光照的问题。这里的错误在于我是按设备建立顺序逐步更新设备的状态。但电路中受控窗帘收到光照的影响。所以我必须先将电路里的总光照先进行更新其次再对受控窗帘进行更新。
点击查看代码
private double getTotalLightIntensity() {double totalIntensity = 0;for (Device device : devices.values()) {if (device instanceof LightBulb) {LightBulb lightBulb = (LightBulb) device;double brightness = Double.parseDouble(lightBulb.getState()); // 将字符串表示的亮度转换为数值totalIntensity += brightness;} else if (device instanceof FluorescentLight) {FluorescentLight fluorescentLight = (FluorescentLight) device;double brightness = Double.parseDouble(fluorescentLight.getState());totalIntensity += brightness;}}return totalIntensity;}
互斥开关问题。我最开始的设计思路是把互斥开关引脚12,引脚13作为两个不同名的设备。发现这与我代码中的输入信息就有冲突了。然后转变思路同一设备名但是用不同的引脚信息来区分。
其次是互斥开关开断问题。一开始的设计思路只能处理开关样式,我一直搞不通如何切换另一个引脚的联通状态。经过和同学的讨论我才用判断方法。建立或者改变互斥开关的状态时,去获取建立时的引脚信息,根据引脚信息和状态是否一致来更新自己的电阻状态和通路状态。问题得以解决。
点击查看代码
public boolean tonglu(){if (state){if("1".equals(yinjiao1) && "2".equals(yinjiao2) || "2".equals(yinjiao1) && "1".equals(yinjiao2)){setResistance("1","2");return true;}}else if(!state){if("1".equals(yinjiao1) && "3".equals(yinjiao2) || "3".equals(yinjiao1) && "1".equals(yinjiao2)){setResistance("1","3");return true;}}return false;}
4.改进思路
为了判断电路的联通,我在组建电路完成后寻找每个开关设备的状态,并一步步寻找是否闭合或断开然后统计电路的开路情况。但是每次这样循环遍历的操作十分需要资源。
设想是否可以在调用控制设备状态时做好标记,然后根据标记直接判断电路联通状态。
二.题目集八,7-1 家居强电电路模拟程序-4
1.前言
知识点考查和难度:
本题在上次迭代基础上增加了二极管,以及电路的多并联(并联包含并联)。并且需要输出各设备的各个引脚状态。还新增了电流限额,超过电流限额不工作。主要难度体现在引脚问题和并联嵌套电路的处理,以及限额电流的计算。
2.设计分析
对于每个电器类(如开关、分档调速器、白炽灯等),需要新增一个数据结构来存储管脚电压信息。
在每个电器类中新增一个属性 maxCurrent,用于存储该电器的最大限定电流。根据题目中给出的各类电器最大限定电流,在电器类的初始化或构造函数中设置相应的 maxCurrent 值。
短路检测应在其他功能(如管脚电压显示、电流限制检查等)之前进行,一旦检测到短路,立即终止后续的计算和输出流程,以确保程序的正确性和效率。
原有的电路数据结构可能需要进行扩展,以支持并联电路中包含并联电路的情况。
创建一个新的 Diode 类来表示二极管元件,继承自通用的电器元件基类,在电路计算过程中,根据二极管两端的电压和电流方向来确定其导通 / 截止状态,并设置相应的电阻值。
如果电流从左至右流过(即 pin1 电压大于 pin2 电压),将 state 设置为 "conduction",电阻设置为 0;如果电流从右至左流动(即 pin2 电压大于 pin1 电压),将 state 设置为 "cutoff",电阻设置为无穷大
设计类图如下:
时序图如下:
3.踩坑心得
短路检测问题:
短路判断条件的准确性,在电路中,短路由于多种原因引起的,如导线直接连接、电器内部故障等,准确判断短路情况可能比较困难,尤其是在复杂电路中,出现误判或漏判的情况。
当检测到短路时,需要及时停止后续的计算和输出操作,以避免不必要的计算和可能出现的错误。但这可能会导致程序流程的突然中断,可能会影响程序的稳定性和可维护性。
我的短路检测样例就没有全部通过,经过对整个电路每条分路一步步判断才找出未判断的短路情况。非常的麻烦。所以我感觉我需要对电路连接优化一下代码。
点击查看代码
if(!manager.getshortdevice()){System.out.println(manager.getStatus());}else {System.out.println("short circuit error");}
并联电路中包含并联问题:
嵌套的并联和串联电路数据结构可能会变得非常复杂,导致代码的可读性和可维护性降低。在处理这种复杂数据结构时,容易出现索引错误、数据访问错误等问题。
我一开始没有考虑到并联中还有并联而无穷之。单纯就是循环嵌套的去处理,导致错误。
解决:
需要将计算电阻的函数进行封装,然后采用递归的方法进行计算,递归地处理嵌套的电路结构。
4.改进思路:
整体架构与设计
模块化设计:
将电路计算、电器元件类、输出显示等功能进一步模块化。例如,创建专门的模块来处理电路的拓扑结构分析、电学参数计算、二极管状态处理、错误检测(短路、电流超限等)以及输出格式化等。这样可以使代码结构更加清晰,每个模块职责明确,便于维护和扩展。
对于复杂的电路计算算法,可以考虑使用设计模式,如策略模式来处理不同类型的电路计算(串联、并联、包含二极管的电路等),使得代码更具灵活性和可扩展性。
数据结构与算法
优化数据结构:
对于表示电路的数据结构,可以考虑使用图数据结构(如邻接表或邻接矩阵)来更直观地表示电路元件之间的连接关系,特别是对于复杂的并联嵌套电路。这样可以方便地进行电路的遍历和分析,提高计算效率和准确性。
在存储电器元件的属性时,除了基本的数值类型,可以使用枚举类型来表示一些状态信息,如二极管的导通 / 截止状态、电器的工作状态等,这样可以提高代码的可读性和可维护性,同时减少因状态表示不一致导致的错误。
三.总结
本次博客是最后一次,整个大作业也结束了。对于本次大作业我觉得我有很多不足,首先是功能不能够达到测试点的要求,得分不高。表示我的代码逻辑能力和水平都有很多不足,需要我多学习多练习进行弥补。其次是代码设计问题。在课堂上学习过很多设计模式方法,但是我在设计过程中总是从功能出发,没有考虑设计性。导致每次代码迭代需要修改很多甚至是推倒重来。
整个电路系统按照功能划分为多个层次和模块。最底层是电器元件类,负责自身属性和行为的定义;往上一层是电路连接与计算模块,专注于处理电路的拓扑结构分析、电学参数计算等核心逻辑;再往上是用户交互与输出模块,负责接收用户输入的电路信息、展示计算结果以及错误提示等。
这种分层架构使得各层之间职责分明,降低了耦合度。当修改底层电器元件的实现细节,如优化二极管的导通截止判断算法时,只要接口保持不变,上层的电路计算和用户交互模块几乎不需要改动。模块化开发同样功不可没,将不同的功能封装在独立的 Java 包中,例如 device 包存放电器元件类,circuit 包负责电路相关逻辑,ui 包处理用户界面交互。每个包内的类协同工作,对外提供统一的功能接口,方便团队协作开发,不同成员可以专注于不同模块,减少代码冲突,提高开发效率。我想我需要学习这样的思想与眼光。在解决一些复杂问题时,我需要设计模式提供优雅的解决方案。
此次大作业是一次理论与实践深度结合的宝贵经历。通过运用 Java 设计方法构建电路系统,不仅让我使用了面向对象编程、数据结构与算法、设计模式等核心技术在实际项目中的应用,更培养了自己从软件架构层面思考问题、解决问题的能力。
展望未来,我意识到还有很多可以改进的空间。在代码质量上,可以进一步引入代码静态分析工具,查找潜在的代码异味和错误,持续优化代码结构;在功能拓展方面,考虑结合图形化界面库,为用户提供更加直观、便捷的设计与分析工具;在性能优化上,不断提升先进性。
总之,这次大作业为我打开了一扇通往软件设计的大门,让我在编程道路上迈出了坚实的一大步,也为今后的学习和研究积累了丰富的经验。