一.前言
家居强电电路模拟程序-3:
1.知识点:
- 面向对象编程 (OOP):
类和对象: 需要定义各种设备(开关、调速器、灯、风扇、窗帘等)的类,并创建这些类的对象。
继承: 使用继承来创建设备层次结构,例如,Lamp
类作为FilamentLamp
和DaylightLamp
的父类。
多态: 通过接口或抽象类实现不同设备的行为,例如,setVoltageIn
和getVoltageOut
方法在不同设备类中的实现。 - 电路基础知识:
电压、电流、电阻: 理解电压的概念,以及电压如何驱动设备工作,以及电阻对电路的影响。
串联电路和并联电路: 理解串联和并联电路的特性,包括电压分配和电阻计算。
短路: 虽然题目中不考虑直接短路,但需要理解短路的概念,以及如何通过开关状态来模拟短路。 - 数据结构:
Map: 使用HashMap
来存储设备,并使用设备 ID 作为键。
List: 使用ArrayList
来存储电路中的设备列表。 - 字符串处理:
字符串解析: 需要解析输入字符串,提取设备 ID、引脚信息、控制命令等。
字符串格式化: 需要格式化输出,例如,保留两位小数、显示开关状态等。 - 逻辑控制:
条件判断: 使用if-else
语句来处理不同的设备状态和控制逻辑。
循环: 使用for
循环来遍历设备列表,以及处理电路中的设备。 - 数学计算:
比例计算: 需要根据电压差计算灯的亮度、风扇的转速等。
电阻计算: 需要计算串联和并联电路的等效电阻。 - 设备模拟:
开关、调速器、互斥开关: 理解这些控制设备的工作原理,并模拟它们的状态转换和输出。
灯、风扇、窗帘: 理解这些受控设备的工作原理,并模拟它们的行为,如亮度、转速、开合程度。
2.题量:题量大
题目中涉及多种设备类型,包括开关、调速器、灯、风扇、互斥开关和窗帘。
题目涉及串联电路、并联电路和主电路,并且支持串联电路中包含其他串联电路以及多个并联电路串联的情况。
题目需要处理多种输入类型,包括设备信息、连接信息、控制信息和电路信息。
题目需要输出各种设备的状态和参数。
3.难点:
复杂设备逻辑:
不同设备有各自的状态或功能,比如互斥开关的三引脚逻辑、调速器的电压倍数输出、窗帘的光照强度控制逻辑等,需要详细理解题意和实现逻辑。
电路解析与嵌套逻辑:
电路信息输入包含了串联电路和并联电路的嵌套结构,并允许电路中包含其他电路的情况。这种递归解析电路的逻辑较为复杂。
动态状态更新:
所有设备状态根据控制设备的调整需要动态实时计算,依赖输入电压、设备电阻等参数,需要同时考虑设备的连线关系及输出规则。
逻辑复杂:
电路的连接和控制逻辑比较复杂,需要仔细分析和设计。
代码量大:
实现所有功能需要编写较多的代码,包括各种设备的类、电路的计算逻辑、输入输出处理等。
调试困难:
由于电路的复杂性,调试过程会比较困难,需要仔细检查代码和逻辑。
家居强电电路模拟程序-4:
1.知识点:
- 面向对象编程 (OOP):
类和对象: 需要定义各种设备(开关、调速器、灯、风扇、窗帘、二极管等)的类,以及电路(串联、并联)的类,并创建这些类的对象。
继承: 使用继承来创建设备层次结构,例如,Lamp
类作为FilamentLamp
和DaylightLamp
的父类。
多态: 通过接口或抽象类实现不同设备的行为,例如,setVoltageIn
、getVoltageOut
和calculateCurrent
方法在不同设备类中的实现。 - 电路基础知识:
电压、电流、电阻: 理解电压、电流和电阻的概念,以及它们之间的关系(欧姆定律)。
串联电路和并联电路: 理解串联和并联电路的特性,包括电压分配、电流分配和电阻计算。
短路: 理解短路的概念,以及如何检测短路情况。
二极管特性: 理解二极管的单向导电特性,以及正向导通和反向截止的概念。 - 数据结构:
Map: 使用HashMap
来存储设备,并使用设备 ID 作为键。
List: 使用ArrayList
来存储电路中的设备列表。
Set: 可能会用到HashSet
来避免重复添加设备或电路。 - 字符串处理:
字符串解析: 需要解析输入字符串,提取设备 ID、引脚信息、控制命令、电路信息等。
字符串格式化: 需要格式化输出,例如,保留两位小数、显示开关状态、输出电压和电流等。 - 逻辑控制:
条件判断: 使用if-else
语句来处理不同的设备状态和控制逻辑。
循环: 使用for
循环来遍历设备列表,以及处理电路中的设备。 - 数学计算:
比例计算: 需要根据电压差计算灯的亮度、风扇的转速等。
电阻计算: 需要计算串联和并联电路的等效电阻。
电流计算: 需要根据电压和电阻计算电流。 - 设备模拟:
开关、调速器、互斥开关: 理解这些控制设备的工作原理,并模拟它们的状态转换和输出。
灯、风扇、窗帘: 理解这些受控设备的工作原理,并模拟它们的行为,如亮度、转速、开合程度。
二极管: 理解二极管的单向导电特性,并模拟其导通和截止状态。 - 错误处理:
短路检测: 需要检测电路中是否存在短路,并输出错误信息。
电流限制: 需要检测设备的电流是否超过最大限制,并输出错误信息。
2.题量:题量超大
题目中涉及多种设备类型,包括开关、调速器、灯、风扇、互斥开关、窗帘和二极管。
题目涉及串联电路、并联电路和主电路,并且支持串联电路中包含其他串联电路和并联电路,以及多个并联电路串联的情况。
题目需要处理多种输入类型,包括设备信息、连接信息、控制信息和电路信息。
题目需要输出各种设备的状态、参数、引脚电压以及错误信息。
3.难度:
-
电路复杂性:
多层嵌套电路: 题目支持串联电路中包含串联和并联电路,并联电路中也包含并联电路,这种多层嵌套的电路结构使得电路的分析和计算变得非常复杂。
互斥开关: 互斥开关的引入增加了电路的动态性,需要根据开关状态来判断电路的连接方式。
二极管: 二极管的单向导电特性使得电路的电流方向变得复杂,需要根据电压差来判断二极管的导通和截止状态。 -
逻辑复杂性:
状态管理: 需要管理各种设备的状态(开关状态、调速器档位、灯的亮度、风扇的转速、窗帘的开合比例、二极管的导通/截止状态等)。
控制逻辑: 需要根据控制命令来改变设备的状态,并更新电路的连接和电压。
错误处理: 需要检测短路、电流超限等错误,并输出相应的错误信息。
电压和电流计算: 需要根据电路的连接方式和设备特性来计算电压和电流,这涉及到复杂的数学计算和逻辑判断。 -
代码实现难度:
类设计: 需要合理设计各种设备类和电路类,以及它们之间的关系,这需要良好的面向对象设计能力。
算法设计: 需要设计合适的算法来处理电路的连接、电压和电流计算、错误检测等。
代码量: 实现所有功能需要编写大量的代码,这需要良好的代码组织和编写能力。
调试难度: 由于电路的复杂性,调试过程可能会非常困难,需要仔细检查代码和逻辑,以及处理各种边界情况。 -
新增功能难度:
管脚电压显示: 需要在计算电压的同时记录每个管脚的电压,并在输出时按格式输出。
电流限制: 需要在计算电流的同时检测是否超过最大电流,并在输出时加入错误提示。
短路检测: 需要检测电路中是否存在短路,并输出错误信息,这需要仔细分析电路的连接方式。
并联电路包含并联电路: 这使得电路的结构更加复杂,需要递归或迭代的方式来处理。
二极管: 需要模拟二极管的单向导电特性,以及正向导通和反向截止的状态,这增加了电路的复杂性。
4.新增内容:
- 管脚电压显示: 在输出设备状态信息后,需要输出每个设备引脚的电压值。
- 电流限制: 每个设备都有最大电流限制,当实时电流超过最大电流时,需要在输出信息中加入错误提示。
- 短路检测: 如果电路出现短路,需要输出错误信息,并且不输出任何设备信息。
- 并联电路包含并联电路: 支持并联电路中包含并联电路的情况,这增加了电路的复杂性。
- 二极管: 新增二极管元件,需要模拟其单向导电特性,以及正向导通和反向截止的状态。
相较于之前的版本,本次迭代的难度大幅提升,主要体现在以下几个方面:
- 电路结构更加复杂: 支持多层嵌套的电路结构,包括并联电路中包含并联电路。
- 设备类型增加: 增加了二极管,需要模拟其单向导电特性。
- 功能更加完善: 增加了管脚电压显示、电流限制、短路检测等功能。
- 错误处理更加严格: 需要检测各种错误情况,并输出相应的错误信息。
二.设计与分析
1.家居强电电路模拟程序-3
1. 程序结构与功能分析
1.1 整体结构
- 电路定义: 通过读取输入,定义电路的拓扑结构,包括各个元件的连接方式(串联、并联)以及主电路的组成。
- 元件控制: 通过读取输入,控制电路中的开关、调速器等元件的状态。
- 电压计算: 根据电路结构和元件状态,计算各个元件两端的电压。
- 设备状态模拟: 根据电压值,模拟灯泡的亮度、风扇的转速以及窗帘的开合程度。
- 结果输出: 按照类型和 ID 排序,输出所有设备的状态信息。
1.2 主要类及其功能
Device
(抽象类): 所有设备的基类,定义了设备的基本属性(ID、输入电压、输出电压、电阻)和方法(设置输入电压、获取输出电压、toString()
)。
ElectricalDevice
(抽象类): 继承自 Device
,表示电子设备。
ControlDevice
(抽象类): 继承自 Device
,表示控制设备,具有 control()
方法来改变自身状态。
Switch
: 简单的开关,控制电路的通断。
GradualSpeeder
: 逐步调速器,有几个档位。
ContinuousSpeeder
: 连续调速器,可以设置任意值。
MutualExclusionSwitch
: 互斥开关,连接两个引脚中的一个,并且有不同的电阻。
Lamp
(抽象类): 继承自 ElectricalDevice
,表示灯泡,具有 getBrightness()
方法。
FilamentLamp
: 白炽灯,亮度随电压变化。
DaylightLamp
: 日光灯,只有开和关两种状态。
Fan
(抽象类): 继承自 ElectricalDevice
,表示风扇,具有 getRotationalSpeed()
方法。
CeilingFan
: 吊扇,转速随电压变化。
FloorFan
: 落地扇,转速有几个固定档位。
WindowCurtain
: 受控窗帘,开合程度受房间内灯光亮度影响。
SeriesCircuit
: 串联电路,包含多个设备,电压按电阻比例分配。
ParallelCircuit
: 并联电路,包含多个串联电路支路,电压相同。
MainCircuit
: 主电路,是整个系统的顶层电路,负责电压的分配和计算。
1.3 主要功能模块
输入处理: 读取输入,解析电路拓扑结构和控制命令。
设备创建: 根据输入信息创建各种类型的设备。
电路连接: 将设备添加到串联电路、并联电路或主电路中。
控制执行: 根据控制命令,改变控制设备的状态。
电压计算: 根据电路拓扑结构和元件状态,计算各个元件的电压。
设备状态更新: 根据电压值,更新灯泡亮度、风扇转速和窗帘开合度。
结果输出: 按照类型和 ID 排序,输出所有设备的状态信息。
2. 代码流程设计与逻辑分析
2.1 代码流程
- 初始化:
创建Scanner
对象读取输入。
创建HashMap
存储设备、串联电路、并联电路和主电路。
创建ArrayList
存储控制命令。 - 读取输入:
循环读取每一行输入,直到遇到 "end"。
如果输入以 "#T" 开头,则处理串联电路或主电路的定义。
如果输入以 "#M" 开头,则处理并联电路的定义。
否则,将输入作为控制命令添加到commands
列表。 - 执行控制命令:
遍历commands
列表,解析出设备 ID 和操作。
根据设备 ID 获取对应的ControlDevice
对象。
调用control()
方法执行操作。 - 计算电压:
遍历所有MainCircuit
对象,调用applyVoltages()
方法,计算电压。 - 更新窗帘状态:
遍历所有Device
对象,如果对象是WindowCurtain
,重新设置电压,更新窗帘的开合度。 - 输出结果:
使用printDevicesByType()
方法,按照类型和 ID 排序,输出所有设备的状态信息。
2.2 逻辑分析
电路拓扑结构解析:
使用字符串分割,解析输入中的电路 ID 和连接信息。
根据设备 ID 前缀,创建对应的设备对象。
将设备添加到对应的串联电路、并联电路或主电路中。
控制命令执行:
根据设备 ID 获取对应的 ControlDevice
对象。
调用 control()
方法,改变设备状态。
电压计算:
MainCircuit.applyVoltages()
:
首先,计算控制设备(如调速器)对电压的影响。
然后,计算整个主电路的总电阻。
根据总电阻和输入电压,计算每个设备上的电压。
对于并联电路和串联电路,递归计算其内部的电压分配。
SeriesCircuit.calculateResistance()
:
递归计算串联电路的总电阻。
考虑互斥开关的状态,如果引脚不匹配则返回 0。
ParallelCircuit.calculateResistance()
:
递归计算并联电路的总电阻。
如果存在短路情况,返回 0。
设备状态更新:
FilamentLamp
:根据电压值,计算亮度。
DaylightLamp
:根据电压值,设置亮度(开或关)。
CeilingFan
:根据电压值,计算转速。
FloorFan
:根据电压值,设置转速(固定档位)。
WindowCurtain
:根据所有灯泡的亮度,计算窗帘的开合度。
短路逻辑:
ParallelCircuit.calculateResistance()
中,如果一个支路只包含开关且所有开关都闭合,则认为存在短路,总电阻为0。
3. 关键设计点
抽象类和继承: 使用抽象类 Device
、ElectricalDevice
、ControlDevice
、Lamp
和 Fan
来实现代码的复用和扩展。
电路结构: 使用 SeriesCircuit
、ParallelCircuit
和 MainCircuit
类来表示电路的拓扑结构。
递归计算: 使用递归的方式计算串联电路和并联电路的电阻,简化了代码逻辑。
互斥开关: 使用 MutualExclusionSwitch
类模拟互斥开关的行为。
受控窗帘: 使用 WindowCurtain
类模拟受灯光影响的窗帘,实现了设备之间的相互作用。
短路处理: 在并联电路中,如果一个支路只包含开关且所有开关都闭合,则认为存在短路,总电阻为0。
类图:
顺序图:
2.家居强电电路模拟程序-4
1. 程序结构与功能分析
1.1 整体结构
这个程序在之前的版本基础上进行了扩展,更加精细地模拟了电子电路系统。主要变化在于:
- 引脚电压: 引入了
pinVoltage1
和pinVoltage2
来表示设备两个引脚的电压,使得电压计算更加精确。 - 电流限制: 每个设备都有一个
Maxcurrent
属性,表示最大允许电流,如果电流超过这个值,则会输出错误信息。 - 二极管: 新增了
Diode
类,模拟二极管的导通和截止特性。 - 电压信息输出: 在
toString()
方法中,输出设备两个引脚的电压信息。 - 短路检测: 在
MainCircuit
中增加了isShortCircuit()
方法,用于检测电路是否短路。 - 设备状态输出:
getDeviceStatus()
方法返回设备状态信息。
1.2 主要类及其功能
Device
(抽象类):
新增了 Maxcurrent
属性表示最大电流。
新增了 pin1
属性表示引脚1,pinVoltage1
和pinVoltage2
表示两个引脚的电压。
新增了setCurrent()
方法设置电流。
新增了 setPinVoltages()
方法来设置引脚电压。
修改了 toString()
方法,输出设备状态和引脚电压信息,以及是否超过电流限制的错误信息。
新增了 isCurrentExceeded()
方法判断是否超过电流限制。
新增了 getDeviceStatus()
方法返回设备状态信息。
ElectricalDevice
(抽象类): 继承自 Device
,表示电子设备。
ControlDevice
(抽象类): 继承自 Device
,表示控制设备。
Switch
: 简单的开关,控制电路的通断。
GradualSpeeder
: 逐步调速器,有几个档位。
ContinuousSpeeder
: 连续调速器,可以设置任意值。
MutualExclusionSwitch
: 互斥开关,连接两个引脚中的一个,并且有不同的电阻。
Diode
: 二极管,具有导通和截止特性。
Lamp
(抽象类): 继承自 ElectricalDevice
,表示灯泡。
FilamentLamp
: 白炽灯,亮度随电压变化。
DaylightLamp
: 日光灯,只有开和关两种状态。
Fan
(抽象类): 继承自 ElectricalDevice
,表示风扇。
CeilingFan
: 吊扇,转速随电压变化。
FloorFan
: 落地扇,转速有几个固定档位。
WindowCurtain
: 受控窗帘,开合程度受房间内灯光亮度影响。
SeriesCircuit
: 串联电路,包含多个设备,电压按电阻比例分配。
ParallelCircuit
: 并联电路,包含多个串联电路支路,电压相同。
MainCircuit
: 主电路,是整个系统的顶层电路,负责电压的分配和计算。
1.3 主要功能模块
输入处理: 读取输入,解析电路拓扑结构和控制命令。
设备创建: 根据输入信息创建各种类型的设备。
电路连接: 将设备添加到串联电路、并联电路或主电路中。
控制执行: 根据控制命令,改变控制设备的状态。
电压计算: 根据电路拓扑结构和元件状态,计算各个元件的电压,包括引脚电压。
电流计算: 计算通过每个设备的电流。
设备状态模拟: 根据电压值,模拟灯泡的亮度、风扇的转速以及窗帘的开合程度。
短路检测: 检测电路是否短路,并输出错误信息。
电流限制检测: 检测是否有设备超过最大允许电流。
结果输出: 按照类型和 ID 排序,输出所有设备的状态信息,包括引脚电压和是否超过电流限制。
2. 代码流程设计与逻辑分析
2.1 代码流程
- 初始化:
创建Scanner
对象读取输入。
创建HashMap
存储设备、串联电路、并联电路和主电路。
创建ArrayList
存储控制命令。 - 读取输入:
循环读取每一行输入,直到遇到 "end"。
如果输入以 "#T" 开头,则处理串联电路或主电路的定义。
如果输入以 "#M" 开头,则处理并联电路的定义。
否则,将输入作为控制命令添加到commands
列表。 - 执行控制命令:
遍历commands
列表,解析出设备 ID 和操作。
根据设备 ID 获取对应的ControlDevice
对象。
调用control()
方法执行操作。 - 计算电压:
遍历所有MainCircuit
对象,调用applyVoltages()
方法,计算电压。
遍历所有MainCircuit
对象,调用calculateAllPinVoltages()
方法,计算所有引脚电压。 - 更新窗帘状态:
遍历所有Device
对象,如果对象是WindowCurtain
,重新设置电压,更新窗帘的开合度。 - 短路检测:
调用MainCircuit.isShortCircuit()
方法检测电路是否短路,如果短路则输出错误信息并退出程序。 - 输出结果:
使用printDevicesByType()
方法,按照类型和 ID 排序,输出所有设备的状态信息。
2.2 逻辑分析
电路拓扑结构解析:
使用字符串分割,解析输入中的电路 ID 和连接信息。
根据设备 ID 前缀,创建对应的设备对象。
将设备添加到对应的串联电路、并联电路或主电路中。
控制命令执行:
根据设备 ID 获取对应的 ControlDevice
对象。
调用 control()
方法,改变设备状态。
电压计算:
MainCircuit.applyVoltages()
:
首先,计算控制设备(如调速器)对电压的影响。
然后,计算整个主电路的总电阻。
根据总电阻和输入电压,计算每个设备上的电压。
对于并联电路和串联电路,递归计算其内部的电压分配。
SeriesCircuit.calculateResistance()
:
递归计算串联电路的总电阻。
考虑互斥开关的状态,如果引脚不匹配则返回 0。
ParallelCircuit.calculateResistance()
:
递归计算并联电路的总电阻。
如果存在短路情况,返回 0。
MainCircuit.calculateAllPinVoltages()
:
遍历所有组件,计算每个组件的引脚电压。
根据组件类型,计算方式不同。
对于控制设备,直接计算引脚电压。
对于串并联电路,递归调用其内部的计算方法。
设备状态更新:
FilamentLamp
:根据电压值,计算亮度。
DaylightLamp
:根据电压值,设置亮度(开或关)。
CeilingFan
:根据电压值,计算转速。
FloorFan
:根据电压值,设置转速(固定档位)。
WindowCurtain
:根据所有灯泡的亮度,计算窗帘的开合度。
Diode
: 根据引脚电压判断是否正向偏置,更新状态。
短路逻辑:
ParallelCircuit.calculateResistance()
中,如果一个支路只包含开关且所有开关都闭合,则认为存在短路,总电阻为0。
MainCircuit.isShortCircuit()
中,如果主电路只包含开关且所有开关都闭合,则认为存在短路。
电流限制:
在 Device
类中,增加了 Maxcurrent
属性和 isCurrentExceeded()
方法,用于判断设备是否超过最大允许电流。
3. 关键设计点
引脚电压和电流: 引入了引脚电压和最大电流的概念,使得电路模拟更加精细。
二极管模拟: 新增了 Diode
类,模拟二极管的导通和截止特性。
短路检测: 在 MainCircuit
中增加了短路检测功能,提高了程序的健壮性。
电流限制检测: 在 Device
类中增加了电流限制检测功能,使得电路模拟更加真实。
设备状态输出: getDeviceStatus()
方法返回设备状态信息,方便输出。
类图:
顺序图:
三.采坑心得
家居强电电路模拟程序-3
1.单串联电路含互斥开关问题:只有一条主电路并且含有互斥开关
解决方法:解析时把互斥开关2,3引脚储存起来,然后计算电阻时应用
测试点1:
#T3:[VCC B2-1] [B2-2 K1-1] [K1-2 S1-1] [S1-2 H1-1] [H1-3 GND]
#K1
end
结果1:
@K1:closed
@B2:0
@H1:closed
@S1:100%
测试点2:
#T3:[VCC B2-1] [B2-2 K1-1] [K1-2 S1-1] [S1-2 H1-1] [H1-3 GND]
#K1
#H1
end
结果2:
@K1:closed
@B2:87
@H1:turned on
@S1:80%
2.多互斥开关问题
解决方法:首先收集所有互斥开关,如果有互斥开关,检查所有开关的引脚是否匹配
测试点:
#T1:[IN H1-1] [H1-2 H2-1] [H2-2 D2-1] [D2-2 GND]
#T2:[IN H1-1] [H1-3 H2-1] [H2-3 D1-1] [D1-2 GND]
#M1:[T1 T2]
#T4:[IN K3-1] [K3-2 B2-1] [B2-2 OUT]
#T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
#M2:[T4 T5]
#T3:[VCC K2-1] [K2-2 M1-IN] [M1-OUT M2-IN] [M2-OUT GND]
#H1
#H2
#K1
#K2
end
结果:
@K1:closed
@K2:closed
@K3:turned on
@B1:74
@B2:0
@D1:112
@D2:0
@H1:turned on
@H2:turned on
3.排序问题:字典排序,例如K11应该在K2前面
解决方法:使用了 Java 泛型、流式 API
测试点:
#T1:[IN D2-1] [D2-2 H1-2] [H1-1 OUT]
#T2:[IN D1-1] [D1-2 H1-3] [H1-1 OUT]
#T6:[IN K4-1] [K4-2 OUT]
#M1:[T1 T2 T6]
#T4:[IN B2-1] [B2-2 OUT]
#T5:[IN K1-1] [K1-2 B1-1] [B1-2 OUT]
#M2:[T4 T5]
#T10:[IN K11-1] [K11-2 R2-1] [R2-2 OUT]
#T9:[IN R1-1] [R1-2 OUT]
#M3:[T9 T10]
#T3:[VCC K2-1] [K2-2 M1-IN] [M1-OUT M2-IN] [M2-OUT M3-IN] [M3-OUT GND]
#K1
#K2
#K4
#H1
#K11
end
结果:
@K1:closed
@K11:closed
@K2:closed
@K4:closed
@B1:147
@B2:147
@R1:180
@R2:180
@D1:0
@D2:0
@H1:turned on
4.计算并联电路电阻问题:
一开始我的计算逻辑是
改为直接返回倒数就对了:
家居强电电路模拟程序-4
这次题目设计的嵌套算法并没有完善,只写了比较基础的,像短路,回路,断路等情况并没有考虑,所以计算的引脚电压只对了一小部分基础的。
四.改进建议
家居强电电路模拟程序-3
代码整体结构与设计
- 单一职责原则 (SRP):
Device
类及其子类目前承担了设备状态管理、电压计算、以及输出格式化等多种职责。可以考虑将输出格式化(toString()
方法)分离到单独的类或接口中,例如使用Formatter
接口来实现不同的输出格式。
MainCircuit
的applyVoltages
方法过于复杂,承担了计算总电阻、应用电压、以及处理控制设备影响等多种职责。可以拆分成更小的、职责更明确的方法。 - 开闭原则 (OCP):
目前添加新的设备类型需要在createDevice
方法中修改,这违反了开闭原则。可以使用工厂模式或反射机制来动态创建设备,避免修改createDevice
方法。
MainCircuit
中的电压计算逻辑,如果需要添加新的电压计算方式,需要修改代码。可以使用策略模式来处理不同的计算方式。 - 代码复用:
CeilingFan
和FloorFan
中电压和转速的计算逻辑有重复代码,可以提取到父类Fan
中,使用模板方法模式来处理不同类型的风扇。 - 可读性:
calculateResistance
方法的逻辑过于复杂,可以拆分成更小的、职责更明确的方法。 - 可测试性:
目前的Main
类承担了太多的职责,包括输入处理、设备创建、电压计算和输出。可以考虑将这些逻辑分离到不同的类中,方便进行单元测试。
Device
及其子类中的电压计算逻辑可以单独测试,确保计算的正确性。
具体代码改进建议
- 使用工厂模式创建设备:
创建一个DeviceFactory
接口,定义createDevice(String id)
方法。
为每种设备类型创建一个工厂类,实现DeviceFactory
接口。
在Main
类中使用工厂类来创建设备,避免修改createDevice
方法。 - 使用策略模式处理电压计算:
创建一个VoltageCalculator
接口,定义calculate(double voltageIn, Device device)
方法。
为每种设备类型创建一个电压计算类,实现VoltageCalculator
接口。
在Device
类中使用VoltageCalculator
来计算电压,避免在setVoltageIn
方法中编写复杂的计算逻辑。 - 使用模板方法模式处理风扇:
在Fan
类中定义calculateRotationalSpeed(double voltageIn)
抽象方法。
在CeilingFan
和FloorFan
中实现calculateRotationalSpeed
方法,处理不同的转速计算逻辑。 - 分离输出格式化逻辑:
创建一个DeviceFormatter
接口,定义format(Device device)
方法。
为每种设备类型创建一个格式化类,实现DeviceFormatter
接口。
在Main
类中使用DeviceFormatter
来格式化输出,避免在toString
方法中编写复杂的格式化逻辑。 - 拆分
MainCircuit
的applyVoltages
方法:
创建一个VoltageApplier
类,定义apply(MainCircuit circuit)
方法。
在apply
方法中,拆分电压计算、控制设备影响、以及设备电压设置等逻辑。 - 添加异常处理:
在Main
类中添加try-catch
块,处理输入格式错误、设备不存在等异常情况。
在Device
类中添加异常处理机制,处理电压计算错误等情况。
家居强电电路模拟程序-4
代码整体结构与设计
- 单一职责原则 (SRP):
Device
类仍然承担了较多的职责,包括设备状态管理、电压计算、电流限制检查、引脚电压设置以及输出格式化。可以考虑将电流限制检查、引脚电压设置等逻辑分离出去,例如使用专门的CurrentChecker
和PinVoltageSetter
类。
MainCircuit
的applyVoltages
方法仍然承担了较多职责,包括计算总电阻、应用电压、处理控制设备影响,以及现在的电流计算。可以进一步拆分成更小的、职责更明确的方法。
calculateComponentPinVoltages
方法逻辑复杂,可以拆分。 - 开闭原则 (OCP):
createDevice
方法仍然需要修改来添加新的设备类型。可以使用工厂模式或反射机制来动态创建设备,避免修改createDevice
方法。
MainCircuit
中的电压计算逻辑,如果需要添加新的电压计算方式,需要修改代码。可以使用策略模式来处理不同的计算方式。
Device
类中的toString()
方法,如果需要不同的输出格式,需要修改代码。可以使用策略模式或装饰器模式来处理不同的输出格式。 - 代码复用:
CeilingFan
和FloorFan
中电压和转速的计算逻辑有重复代码,可以提取到父类Fan
中,使用模板方法模式来处理不同类型的风扇。
FilamentLamp
和DaylightLamp
中电压设置和亮度计算部分逻辑可以提取到父类Lamp
中。 - 可读性:
calculateResistance
方法的逻辑过于复杂,可以拆分成更小的、职责更明确的方法。
calculateComponentPinVoltages
方法逻辑复杂,可以拆分。 - 可测试性:
目前的Main
类承担了太多的职责,包括输入处理、设备创建、电压计算和输出。可以考虑将这些逻辑分离到不同的类中,方便进行单元测试。
Device
及其子类中的电压计算逻辑可以单独测试,确保计算的正确性。
MainCircuit
的applyVoltages
方法和calculateAllPinVoltages
方法可以单独测试。 - 依赖关系
MainCircuit
依赖了静态变量components
,这会导致代码的耦合性增加,不利于单元测试。
具体代码改进建议
- 使用工厂模式创建设备:
创建一个DeviceFactory
接口,定义createDevice(String id, String pin1)
方法。
为每种设备类型创建一个工厂类,实现DeviceFactory
接口。
在Main
类中使用工厂类来创建设备,避免修改createDevice
方法。 - 使用策略模式处理电压计算:
创建一个VoltageCalculator
接口,定义calculate(double voltageIn, Device device)
方法。
为每种设备类型创建一个电压计算类,实现VoltageCalculator
接口。
在Device
类中使用VoltageCalculator
来计算电压,避免在setVoltageIn
方法中编写复杂的计算逻辑。 - 使用模板方法模式处理风扇和灯泡:
在Fan
类中定义calculateRotationalSpeed(double voltageIn)
抽象方法。
在CeilingFan
和FloorFan
中实现calculateRotationalSpeed
方法,处理不同的转速计算逻辑。
在Lamp
类中定义calculateBrightness(double voltageIn)
抽象方法。
在FilamentLamp
和DaylightLamp
中实现calculateBrightness
方法,处理不同的亮度计算逻辑。 - 分离输出格式化逻辑:
创建一个DeviceFormatter
接口,定义format(Device device)
方法。
为每种设备类型创建一个格式化类,实现DeviceFormatter
接口。
在Main
类中使用DeviceFormatter
来格式化输出,避免在toString
方法中编写复杂的格式化逻辑。 - 拆分
MainCircuit
的applyVoltages
和calculateAllPinVoltages
方法:
创建一个VoltageApplier
类,定义apply(MainCircuit circuit)
方法。
在apply
方法中,拆分电压计算、控制设备影响、以及设备电压设置等逻辑。
创建一个PinVoltageCalculator
类,定义calculate(MainCircuit circuit)
方法。
在calculate
方法中,拆分引脚电压计算逻辑。 - 添加异常处理:
在Main
类中添加try-catch
块,处理输入格式错误、设备不存在等异常情况。
在Device
类中添加异常处理机制,处理电压计算错误、电流超限等情况。 - 移除
MainCircuit
的静态变量
将components
变量改为实例变量,避免静态变量带来的耦合性问题。 - 引入
CurrentChecker
和PinVoltageSetter
创建CurrentChecker
接口,定义check(Device device)
方法,用于检查电流是否超限。
创建PinVoltageSetter
接口,定义set(Device device, double pinVoltage1, double pinVoltage2)
方法,用于设置引脚电压。
在Device
类中使用CurrentChecker
和PinVoltageSetter
来处理电流检查和引脚电压设置。
五.总结
本阶段的两次题目集,不仅仅是简单的编程练习,更像是一场精心设计的旅程,引领我深入探索面向对象编程的精髓,并将其应用于实际的电路模拟场景。我从最初对OOP概念的模糊理解,到逐渐能够灵活运用抽象、封装、继承、多态等特性,构建出具有一定复杂度的设备体系,这本身就是一个巨大的进步。我开始体会到,OOP不仅仅是一种编程范式,更是一种思考方式,它引导我将现实世界中的事物抽象成对象,并定义它们之间的关系和行为。这种思维方式的转变,对我理解和解决复杂问题具有重要的意义。
在电路模拟方面,我不再仅仅满足于实现基本的功能,而是开始思考如何构建一个更加真实、更加灵活的模拟系统。我不仅要计算电路中的电压、电流和电阻,还要考虑各种因素对电路行为的影响,例如开关的状态、控制器的调节、以及互斥开关的选择。这让我认识到,软件开发不仅仅是编写代码,更是将现实世界的问题抽象成计算机可以理解的模型,并用代码来模拟和解决问题的过程。我开始体会到,软件开发不仅仅是一项技术活动,更是一项需要领域知识、逻辑思维、抽象能力和问题解决能力的综合性活动。
设计模式的学习,让我开始从更高的层次来审视代码。我不再仅仅关注如何实现功能,而是开始思考如何设计出更加灵活、可复用、可维护的代码。我尝试在代码中运用工厂模式来动态创建设备,避免了在代码中硬编码设备类型;我尝试使用策略模式来处理不同的电压计算方式,使得代码具有更好的扩展性;我尝试使用模板方法模式来提取风扇和灯泡的通用行为,减少了代码的重复性。这些尝试让我认识到,设计模式不仅仅是“代码模板”,更是解决特定问题的通用方法。我开始体会到,设计模式不仅仅是“怎么写代码”,更是“如何更好地写代码”,它让我从一个“代码搬运工”向一个“代码架构师”迈进。
在代码的可持续改进方面,我开始意识到代码质量的重要性。我不再仅仅满足于代码能够运行,而是开始关注代码的可读性、可维护性、可扩展性和可测试性。我开始尝试使用代码审查来发现代码中的问题,使用单元测试来验证代码的正确性,使用重构来改进代码的结构,使用代码规范来统一代码的风格,以及使用持续集成来自动化构建和测试过程。这些尝试让我认识到,代码质量不仅仅是“写完代码”的目标,更是整个软件开发生命周期的重要组成部分。我开始体会到,软件开发不仅仅是“写代码”,更是“写好代码”,并不断改进代码的过程。
然而,我也清晰地认识到,自己在很多方面仍然存在不足,这些不足不仅仅是技术上的,更是思维方式上的。例如,我对设计模式的理解仍然不够深入,我仍然需要通过更多的实践来掌握它们的精髓;我对复杂电路的模拟仍然存在困难,我仍然需要学习更多的电学知识和模拟技术;我对并发编程、错误处理、代码可测试性和扩展性的掌握仍然不够熟练,我仍然需要通过更多的学习和实践来提高自己的能力。此外,我对代码度量和领域驱动设计等高级概念仍然缺乏了解,我仍然需要通过更多的研究来拓展自己的视野。这些不足,既是挑战,也是我未来学习和研究的动力。
六.学期总结
本学期对Java的系统学习,对我来说是一次意义非凡的旅程。它不仅仅是一门课程的学习,更是一次思维方式的转变,一次对编程世界的全新探索。从最初对Java语法的好奇,到后来逐步深入理解面向对象编程(OOP)的精髓,我经历了从懵懂到逐渐清晰的认知过程。我不再仅仅停留在对代码的表面理解,而是开始思考代码背后的设计思想,开始尝试运用OOP的原则来构建更加模块化、可复用、可维护的代码。这种思维方式的转变,对我理解和解决复杂问题具有重要的意义。
在学习过程中,我不仅仅掌握了Java的基本语法,更重要的是理解了Java的核心特性。我学会了如何使用类和对象来封装数据和行为,如何使用继承和多态来实现代码的扩展和复用,如何使用接口和抽象类来定义规范和约束。我还深入学习了Java的异常处理机制,学会了如何编写健壮的代码来处理各种异常情况;我学习了Java的多线程编程,掌握了如何利用多线程来提高程序的并发性和响应速度;我还接触了一些常用的Java框架,例如Spring和MyBatis,了解了如何使用框架来简化开发过程。这些知识和技能,不仅为我未来的软件开发打下了坚实的基础,也让我对Java的强大功能有了更深刻的认识。
除了技术上的收获,本学期的学习也让我体会到编程的乐趣和挑战。我开始认识到,编程不仅仅是编写代码,更是一种创造性的活动,它需要严谨的逻辑思维、良好的代码习惯和持续学习的精神。我开始体会到,解决一个复杂的编程问题,就像解开一个谜题,需要耐心、细致和坚持不懈的努力。当看到自己编写的代码能够成功运行,并实现预期的功能时,那种成就感是无与伦比的。
同时,我也深刻体会到学习编程的艰辛。在学习过程中,我遇到了各种各样的困难,例如语法错误、逻辑错误、性能问题等等。有时候,我会因为一个小的错误而花费大量的时间去调试,甚至会感到沮丧和迷茫。但是,我并没有放弃,而是通过查阅资料、请教老师和同学、以及反复尝试来解决问题。这种坚持不懈的精神,不仅让我掌握了更多的知识和技能,也让我更加坚定了学习编程的决心。
我想说,感谢老师的悉心教导,他们不仅传授了知识,更重要的是引导我们思考,培养了我们解决问题的能力。感谢同学们的互相帮助,我们一起学习、一起讨论、一起进步,共同度过了这段难忘的学习时光。这段学习旅程虽然充满挑战,但收获的知识和技能将让我受益终生。
展望未来,我将继续深入学习Java,不断探索编程的奥秘,努力成为一名优秀的软件工程师。我将更加注重实践,通过参与更多的项目来提高自己的编程能力;我将更加注重学习新的技术,不断拓展自己的知识面;我将更加注重与他人的交流,通过合作来共同进步。我相信,只要我坚持不懈地努力,就一定能够实现自己的目标。
最后,我想说,Java不仅仅是一门编程语言,更是一扇通往无限可能的大门。我将带着本学期所学到的知识和技能,勇敢地迈向未来的挑战,并用自己的代码来创造更美好的世界。
标签:总结性,题目,计算,引脚,代码,Blog,电路,电压,设备 From: https://www.cnblogs.com/hzh-135/p/18637824