OPP7-8次PTA大作业总结
一,前言
经过第4-6次PTA,对java中的面向对象程序设计的设计原则越来越熟悉。对于java中的单一职责原则,开闭原则,里氏代换原则等类设计原则也进一步理解其中的意义。在后续的面向对象程序设计中也了解到一些类设计模式。例如:简单工厂模式,工厂方法模式,建造者模式,单列模式等。
在7-8次PTA大作业中,我的类设计还存在些不足,以下是我对这三次PTA作业的总结。
二,第七次作业
1.
在第七次作业的要求中,在前一次作业的基础上添加了互斥开关(互斥开关设置了限流电阻,12引脚之间默认电阻为5,13引脚之间默认电阻为10。)和窗帘,而且在电路结构中添加了多个并联电路串联的情况。此次迭代和之前一样涉及到继承和多态。
以下是我的类设计思路:
在上一次PTA迭代中添加以下几种类:
添加Curtains类继继承自ControlledEquipment类(受控电器类),在窗帘类中添加SetProportion()方法,该方法调用DataHouse类获取所有白炽灯和日光灯的亮度数据,以计算窗帘的开闭程度。
添加MutexSwitch类继承自ControlEquipment类(控制设备类),在互斥开关类中添加互斥开关状态成员变量记录开关连接哪个引脚,添加pinName2和pinName3成员变量,用于记录互斥开关连接的串联电路。添加changeSwitchStatus()方法用于调节互斥开关的开闭。
2.类图
3.遇到的问题
在读取互斥开关信息时遇到如下问题:
1.互斥开关在两个串联电路信息中出现两次,原有的代码会创建两次互斥开关对象
2.互斥开关会反接到电路中,导致读取不到反接的互斥开关。
3.互斥开关可能单独接到一个串联电路中,当做普通开关使用。
4.改进
在原先的只读取一个引脚的代码加以修改,读取每一个引脚信息,再加一个if判断,如果在DataHouse中找到引脚中的电器名,则跳过,反之则创建一个对应电器的对象。特殊地,如果在DataHouse中找到互斥开关,则记录当前引脚所在的串联电路
public void CreatPerEquipment(String pin, String name, String SeriesName, SeriesElectric series) { if ((pin.equals("2") || pin.equals("3") || pin.equals("1")) && DataHouse.findEquipment(name) == null) { Equipment equipment = EquipmentFactory.createEquipment(name); if (equipment instanceof MutexSwitch) { MutexSwitch mutexSwitch = (MutexSwitch) equipment; if (pin.equals("2")) {mutexSwitch.setPinName2(SeriesName);} else if (pin.equals("3")) {mutexSwitch.setPinName3(SeriesName);} } else if (equipment instanceof SecondaryTube) { SecondaryTube secondaryTube = (SecondaryTube) equipment; if (pin.equals("2")) { secondaryTube.ChangeStatus(); } } series.addEquipment(equipment); DataHouse.Electrics.add(equipment); } else if (pin.equals("IN") && (name.startsWith("T") || name.startsWith("M"))) { series.addEquipment(DataHouse.findEquipment(name)); } else if (( pin.equals("2") || pin.equals("3") || pin.equals("1")) && DataHouse.findEquipment(name) instanceof MutexSwitch) { MutexSwitch mutexSwitch = (MutexSwitch) DataHouse.findEquipment(name); if (pin.equals("2")) {mutexSwitch.setPinName2(SeriesName);series.addEquipment(DataHouse.findEquipment(name));} else if (pin.equals("3")) {mutexSwitch.setPinName3(SeriesName);series.addEquipment(DataHouse.findEquipment(name));} else if (pin.equals("1")) {mutexSwitch.changePositive();} } }
5.缺点
在原有的的代码中添加互斥开关类和窗帘类中,需要在原有的方法中添加新的判断语句,虽然在解决问题时比较方便,但违背了面向对象类设计中的开闭原则。
三,第八次作业
1.
此次迭代中在原来基础上添加二级管,在电路结构上存在包含电路,在并联电路中的串联电路中存在并联电路包含其中的情况。
还有这次迭代还有其他要求:
1)增加管脚电压的显示
在输出每个电器的状态信息后,再依次输出该电器每个管脚的电压。(格式详见输出信息部分)
2)电流限制
电器在工作时,过大的电流会引起电器过热,从而烧坏电路。本次迭代,每个元器件都有最大电流的设置,当实时电流超过最大电流时,在该电器输出信息的最后加入提示“exceeding current limit error”,与前面的信息之间用英文空格分隔。
例如:@B1:190 68-17 exceeding current limit error
本题各类电器的最大限定电流如下:
开关20、分档调速器18、连续调速器18、白炽灯9、日光灯5、吊扇12、落地扇14、互斥开关20、受控窗帘12、二极管8。
3)短路检测
如果电路出现无穷大的电流造成短路,所有元器件信息不输出,仅输出提示“short circuit error”
类设计思路:
在上一次迭代的基础上添加SecondaryTube类继承自 ControlledEquipment类(受控设备类)
在该类中设置成员变量status记录二级管的状态,当status = "conduction"时表示二级管正接接通,
当status = "cutoff"时表示二级管反接断开。
2.类图
3.遇到的问题
由于此次迭代需要输出每个电路元件两端的电势,由于连通电路的方法中遇到断路的串联电路,就会跳过该串联电路,使得在局部断路的电路元件两端的电势都默认为零 .还有互斥开关有三个引脚,需要考虑互斥开关正接反接的问题.
问题代码如下:
public static void ConnectingCircuit() { SeriesElectric seriesElectric = (SeriesElectric) DataHouse.A_SeriesElectric; seriesElectric.setSumResistor(); if (seriesElectric.changeElectricCurrent() == 0 || seriesElectric.getResistor() == 0) { return; } double U = 0; double I = seriesElectric.getPinOne() / seriesElectric.getResistor(); Equipment lastEquip = null; int i = 0; for (Equipment equipment : seriesElectric.getEquipments()) { i++; if (i == 1) { lastEquip = equipment; if (lastEquip instanceof ContinuousGovernor || lastEquip instanceof SplitSpeedGovernor || lastEquip instanceof Switch) { lastEquip.setPinOne(seriesElectric.getPinOne()); U = lastEquip.getPinTwo(); lastEquip.setElectricCurrent(I); } else { U = seriesElectric.getPinOne(); lastEquip.setPinOne(seriesElectric.getPinOne()); lastEquip.setPinTwo(lastEquip.getPinOne() - (U * lastEquip.getResistor()) / seriesElectric.getResistor()); lastEquip.setElectricCurrent(I); ConnectSeriesAndParallel(lastEquip); } } else if (i > 1 && i < seriesElectric.getEquipments().size()) { equipment.setPinOne(lastEquip.getPinTwo()); equipment.setPinTwo(equipment.getPinOne() - (U * equipment.getResistor()) / seriesElectric.getResistor()); lastEquip = equipment; lastEquip.setElectricCurrent(I); ConnectSeriesAndParallel(lastEquip); } else if (i == seriesElectric.getEquipments().size()) { equipment.setPinOne(lastEquip.getPinTwo()); equipment.setPinTwo(seriesElectric.getPinTwo()); equipment.setElectricCurrent(I); ConnectSeriesAndParallel(equipment); } } }
4.改进
在ProcessingData类中添加circuitBreak()方法,该方法源码如下:
public static void circuitBreak(Equipment breakSeries) { SeriesElectric breakSeriesElectric = (SeriesElectric) breakSeries; double pin = breakSeriesElectric.getPinOne(); for (Equipment equipment : breakSeriesElectric.getEquipments()) { if (equipment instanceof ContinuousGovernor || equipment instanceof SplitSpeedGovernor) { equipment.setPinOne(pin); pin = equipment.getPinTwo(); } else if (equipment instanceof SeriesElectric) { equipment.setPinOne(pin); circuitBreak(equipment); pin = equipment.getPinTwo(); } else if (equipment instanceof ParallelElectric) { ParallelElectric parallelElectric = (ParallelElectric) equipment; parallelElectric.setSumResistor(); equipment.setPinOne(pin); equipment.setPinTwo(pin); ParallelConnecting(equipment); if (parallelElectric.getResistor() == -1) { pin = 0; } } else if (equipment instanceof Switch) { Switch switchSeries = (Switch) equipment; equipment.setPinOne(pin); if (switchSeries.getSwitchStatus() == 0) { pin = 0; } equipment.setPinTwo(pin); } else if (equipment instanceof MutexSwitch) { MutexSwitch mutexSwitch = (MutexSwitch) equipment; if (mutexSwitch.isPassage(breakSeriesElectric.getName())) { equipment.setPinOne(pin); equipment.setPinTwo(pin); } else { if (mutexSwitch.getPositive()) { equipment.setPinOne(pin); pin = 0; mutexSwitch.setPinThree(pin); } else { mutexSwitch.setPinThree(pin); pin = 0; mutexSwitch.setPinTwo(pin); } } } else if (equipment instanceof SecondaryTube) { SecondaryTube secondaryTube = (SecondaryTube) equipment; equipment.setPinOne(pin); if (secondaryTube.getStatus().equals("cutoff")) { pin = 0; } equipment.setPinTwo(pin); } else { equipment.setPinOne(pin); equipment.setPinTwo(pin); } } breakSeriesElectric.setPinTwo(pin); }
在ConnectingCircuit()(注:该方法用于连接电路传递电势)方法中如果该串联电路没有断路,则正常传递电势。如果断路则将该串联电路对象传入circuitBreak(Equipment breakSeries)方法中,在circuitBreak中进行传递断路电路的电势的操作,如断路电路中遍历到断路的开关,互斥开关或反接的二极管,则将传出的电势变为零。
5.缺点
经过多次迭代每个方法逐渐变得复杂,用到的if语句较多,还需进一步改进。
四,总结
经过这两次PTA的迭代,我对面向对象的类设计从逐渐熟悉到更加熟练的运用。在这段学习期间,也学到了许多类设计原则如组合模式,桥接模式,单例模式,工厂模式等类设计模式。我虽然了解这些类设计原则但还缺少许多实践。在PTA作业中运用的设计模式少,说明我在许多类设计模式中缺少理解,不知道某些设计模式在什么时候恰当的运用。
在四次家庭电路迭代中也让我收获了许多,电路的串并联的连接和电路结构的变化这一个抽象问题,在代码中一 一实现过程中,使我的类设计能力进一步提高。
在7-8次PTA作业中,虽然我的类设计能力进一步提升,但是在定义方法的规范性也需要继续改进。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~