Java大作业7-8次总结性BLOG

  • 前言

    • 本次BLOG由第7和第8次的大作业家居强电电路模拟程序- 3和家居强电电路模拟程序 -4组成,其中家居强电电路模拟程序2涉及到各个受控设备电压的计算,状态输出,以及开关状态的判断,并新添加了互斥开关和受控窗帘两个设备,同时在电路的种类中新添加了多个并联电路串联在一起的情况以及一条串联电路中包含其他电路的情况。家居强电电路模拟程序4由前三次综合迭代升级而来,在3的基础上增加了各个管脚电压的显示、电流限制、短路检测以及新的电路情况。这两次大作业的重点为多种子类的继承设计以及如何将具体逻辑抽象化为代码,本文将总结这两次大作业的知识点,以及难度,并分析每一道题目的核心内容和实现方法。
  • 家居强电电路模拟程序-3

    • 题目分析

      • 本题要求设计一个智能家居强电电路模拟系统。该系统需要模拟控制设备和受控设备的行为,并根据输入信息输出设备的状态。以下是对题目的详细分析和实现要点:

      功能需求分析

      1. 控制设备模拟

        • 开关:具有两种状态(0和1)。当状态为0时,输出电位为0;当状态为1时,输出电位等于输入电位。
        • 分档调速器:模拟4档调速器,输出电位为输入电压的0、0.3、0.6、0.9倍。
        • 连续调速器:输出电位为档位参数(范围为0.00-1.00)乘以输入电压。
        • 互斥开关:三个引脚:1为汇总引脚,2和3为分支引脚,具有两种状态:接通1-2,引脚1和3断开;接通1-3,引脚1和2断开。其默认状态为:1与2接通(closed),1与3断开(turned on)。
      2. 受控设备模拟

        • 灯具
          • 白炽灯:亮度与电位差成正比,最大亮度为220V对应200lux。
          • 日光灯:亮度为180lux,当电位差不为0时亮。
        • 吊扇:工作电压区间为80V-150V,转速与电压差成正比,最大转速为360转/分钟。
        • 窗帘:最低工作电压为50V;,根据电路中所有灯具的总光照强度控制打开比例,其具体比例如下:
          [0,50)lux:窗帘全开(100%);
          [50,100)lux:窗帘打开80%;
          [100,200)lux:窗帘打开60%;
          [200,300)lux:窗帘打开40%;
          [300,400)lux:窗帘打开20%;
          ≥400lux:窗帘关闭(0%)。
      3. 输入信息

        • 设备信息:用标识符区分设备类型,编号区分实例,如K1表示编号为1的开关,L2表示编号为2的连续调速器。
          输入设备的引脚格式为设备标识-引脚编号,如K1-1。

        • 连接信息:用[]表示一组连接在一起的设备引脚,格式如[K1-1 K3-2]表示K1的1引脚与K3的2引脚相连。

        • 控制设备调节信息:用于改变设备状态或档位。开关和互斥开关:
          K编号:切换开关状态;
          H编号:切换互斥开关状态。

        • 电源接地标识:VCC为220V,GND为0V。

        • 串联电路信息

          • #T表示一条串联电路,格式如:#T1:[IN K1-1] [K1-2 D2-1] [D2-2 OUT]
        • 并联电路信息

          • #M表示一条并联电路,由多条串联电路组成,格式如:#M1:[T1 T2 T3]
      4. 输入信息

      • 输出所有设备的状态或参数,按以下规则:
        • 输出顺序:开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇、落地扇、互斥开关、受控窗帘。
        • 格式:
          • 开关状态:@K1:turned on@K1:closed
          • 分档调速器:@F1:2(表示档位)。
          • 连续调速器:@L1:0.60(档位参数保留两位小数)。
          • 灯具亮度:@B1:190
          • 风扇转速:@A1:120
          • 互斥开关:@H1:turned on@H1:closed
          • 窗帘:@S1:80%(窗帘打开比例)。

      实现要点

      1. 数据结构设计
      • 设计设备类,包含以下属性:
        • 开关类(Switch):状态、输入/输出引脚;
        • 调速器类(调速器类基类 + 分档/连续调速器子类):档位、输入电压;
        • 灯具类:电阻、电位差、亮度;
        • 风扇类:电阻、电位差、转速;
        • 互斥开关类:引脚状态、电阻;
        • 窗帘类:工作电压、光照强度控制。
      • 每类设备需实现方法,用于计算其输出电压、亮度或转速等。
      1. 输入解析
      • 逐行解析输入:
        • 设备和连接信息:用正则表达式提取设备类型、编号、引脚信息;
        • 调节信息:解析控制指令并更新设备状态或档位;
        • 串联和并联电路:构建电路拓扑。
      1. 电路模拟与计算
      • 基于输入信息建立电路模型:
        • 电压分配:根据电路连接信息计算各节点的电压;
        • 电流计算:依据欧姆定律(V=IR)计算电流。
      • 模拟设备行为:
        • 根据输入电压或电位差,计算灯具亮度、风扇转速和窗帘状态等。
      1. 输出处理
      • 按题目要求的顺序输出所有设备的状态或参数。
      • 确保数值格式正确,如连续调速器保留两位小数,输出亮度或转速取整数。

  • 设计与分析

    • 整体逻辑

      1. 设备类及其子类

        • 代码中定义了多个设备类,每个类代表一种设备类型,如开关、调速器、灯具和风扇等。
        • 每个设备类都实现了 Device 抽象类,定义了更新状态和获取状态的方法。
        • 控制设备类(如 SwitchSpeedControllerContinuousSpeedController)实现了控制逻辑,通过输入电压和设备状态计算输出电压。
        • 受控设备类(如 LightFan)根据输入电压更新自身状态,如亮度或转速。
      2. 电路管理

        • SmartHomeCircuit 类负责管理整个电路系统,包括设备的存储和连接。
        • 使用 Map 存储设备,允许通过设备标识符快速访问设备实例。
        • 连接请求存储在一个列表中,待所有输入处理完毕后统一处理连接。
        • processConnections() 方法遍历连接请求,根据连接关系更新设备的输入电压。
      3. 命令解析

        • CommandParser 类负责解析输入命令,识别并处理连接命令和控制命令。
        • parseConnectionCommand() 方法解析连接命令,创建设备实例并记录连接关系。
        • parseControlCommand() 方法解析控制命令,调整设备状态(如开关状态切换、调速器档位调整)。
      4. 输入处理

        • 主程序通过 Scanner 从标准输入读取命令。
        • 根据命令格式(连接命令或控制命令),调用 CommandParser 进行解析。
        • 连接命令用方括号表示,控制命令用 # 开头。
      5. 状态更新与输出

        • processConnections() 方法在所有输入命令处理完毕后执行,更新设备的连接状态。
        • displayStates() 方法输出所有设备的状态,按照设备类型和编号排序输出。
        • 使用 TreeMap 对设备进行分类和排序,确保输出顺序符合要求(开关、分档调速器、连续调速器、白炽灯、日光灯、吊扇)。
    • 源码分析

      1. 设备类及其子类

        Device

        • 属性

          • 抽象类,没有具体属性。
        • 方法

          • updateState(double inputVoltage):抽象方法,用于更新设备状态。
          • getStatus():抽象方法,用于获取设备的当前状态。

        此类是所有设备的基类,定义了设备的基本接口。

        VCC

        • 继承:继承自 Device 类。

        • 属性

          • inputVoltage:固定为220V,表示电源电压。
        • 方法

          • updateState(double inputVoltage):不做任何操作。
          • getStatus():返回空字符串。

        此类用于表示电源设备,提供固定的电压输出。

        Ground

        • 继承:继承自 Device 类。

        • 属性

          • outputVoltage:固定为0V,表示接地电压。
        • 方法

          • updateState(double inputVoltage):不做任何操作。
          • getStatus():返回空字符串。

        此类用于表示接地设备,输出电压为0。

        ControlDevice

        • 继承:继承自 Device 类。

        • 属性

          • inputVoltage:输入电压。
          • outputVoltage:输出电压。
        • 方法

          • control():抽象方法,用于控制设备输出。
          • getOutputVoltage():返回设备的输出电压。

        此类用于表示具有控制功能的设备,是控制设备的抽象基类。

        ExclusiveSwitch

        • 继承:继承自 ControlDevice 类。

        • 属性

          • currentPin: int类型,表示当前接通的引脚(2或3)
          • pin1Voltage: double类型,引脚1(汇总引脚)的电压
          • pin2Voltage: double类型,引脚2(上分支引脚)的电压
          • pin3Voltage: double类型,引脚3(下分支引脚)的电压
          • RESISTANCE_12: static final double类型,1-2引脚间电阻(5Ω)
          • RESISTANCE_13: static final double类型,1-3引脚间电阻(10Ω)
        • 方法

          • ExclusiveSwitch()
          • 构造方法
          • 初始化互斥开关,默认接通引脚2
            - control():根据开关状态设置输出电压。
            - updateState(double inputVoltage):更新输入电压并调用 control()
            - getStatus():返回开关状态。
        • toggle()

          • 切换互斥开关状态
          • 在引脚2和引脚3之间切换
          • 调用control()更新电压状态
        • control()

          • 重写父类方法
          • 根据currentPin更新各引脚电压
          • 当接通引脚2时:pin2Voltage = inputVoltage, pin3Voltage = 0
          • 当接通引脚3时:pin2Voltage = 0, pin3Voltage = inputVoltage
        • updateState(double inputVoltage)

          • 重写父类方法
          • 更新输入电压
          • 调用control()重新计算输出状态
        • getStatus()

          • 重写父类方法
          • 返回当前接通引脚的编号
        • getResistance()

          • 重写父类方法
          • 返回当前接通路径的电阻值
          • 引脚2接通时返回RESISTANCE_12
          • 引脚3接通时返回RESISTANCE_13

        SpeedController

        • 继承:继承自 ControlDevice 类。

        • 属性

          • level:整数,表示调速档位。
        • 方法

          • upLevel():增加档位。
          • downLevel():减少档位。
          • getLevelFactor():根据档位返回相应的因子。
          • control():根据档位因子调整输出电压。
          • updateState(double inputVoltage):更新输入电压并调用 control()
          • getStatus():返回当前档位。

        此类用于表示档位调速器,通过档位控制输出电压。

        ContinuousSpeedController

        • 继承:继承自 ControlDevice 类。

        • 属性

          • speedFactor:双精度浮点数,表示调速因子。
        • 方法

          • setSpeedFactor(double factor):设置并限制调速因子在0到1之间,调用 control()
          • control():根据调速因子调整输出电压。
          • updateState(double inputVoltage):更新输入电压并调用 control()
          • getStatus():返回调速因子。

        此类用于表示连续调速器,通过调速因子控制输出电压。

        ControlledDevice

        • 继承:继承自 Device 类。

        • 属性

          • inputVoltage:输入电压。
          • outputVoltage:输出电压。
        • 方法

          • updateState(double inputVoltage):抽象方法,用于更新设备状态。

        此类用于表示受控设备,是受控设备的抽象基类。

        Light

        • 继承:继承自 ControlledDevice 类。

        • 属性

          • brightness:整数,表示灯光亮度。
        • 方法

          • updateState(double inputVoltage):抽象方法,由子类实现。
          • getStatus():返回亮度。

        此类用于表示灯具设备,控制亮度。

        Fan

        • 继承:继承自 ControlledDevice 类。

        • 属性

          • speed:整数,表示风扇速度。
        • 方法

          • getSpeed():返回风扇速度。
          • setSpeed(int speed):设置风扇速度。
          • updateState(double inputVoltage):根据输入电压更新风扇速度。
          • getStatus():返回速度。

        此类用于表示风扇设备,控制转速。

        IncandescentLight

        • 继承:继承自 Light 类。

        • 方法

          • updateState(double inputVoltage):根据输入电压更新亮度。

        此类用于表示白炽灯,控制亮度。

        FluorescentLight

        • 继承:继承自 Light 类。

        • 方法

          • updateState(double inputVoltage):根据输入电压设置亮度。

        此类用于表示日光灯,控制亮度。
        ControlledCurtain

        • 继承:继承自 ControlledDevice 类。
        • 属性
          • openRatio: double类型,表示窗帘开启比例(0.0-1.0)
          • MIN_VOLTAGE: static final double类型,最小工作电压(50.0V)
        • 方法
          • updateState(double inputVoltage)
            • 重写父类方法
            • 更新窗帘状态
            • 根据输入电压和光照强度调整窗帘开启比例
            • 电压低于MIN_VOLTAGE时窗帘全开
          • calculateTotalLux()
            • 私有方法
            • 计算所有灯的总光照强度
            • 待实现方法,当前返回0
          • getStatus()
            • 重写父类方法
            • 返回窗帘开启比例,保留两位小数
          • getResistance()
            • 重写父类方法
            • 返回窗帘电机的电阻值(15Ω)

        2. 电路管理

        SmartHomeCircuit

        • 属性

          • devices:存储设备的映射,键为设备标识符。
          • connectionRequests:存储连接请求的列表。
        • 方法

          • getDevice(String deviceId):获取设备实例。
          • addDevice(String deviceName, Device device):添加设备。
          • addConnectionRequest(String deviceId1, String deviceId2):添加连接请求。
          • processConnections():处理连接请求,更新设备状态。
          • connectDevices(String deviceId1, String deviceId2):根据连接关系更新设备状态。
          • displayStates():输出设备状态。

        此类用于管理智能家居电路,处理设备的连接和状态更新。

        3. 命令解析

        CommandParser

        • 属性

          • circuitSmartHomeCircuit 的实例。
        • 方法

          • parseConnectionCommand(String input):解析连接命令,创建设备并记录连接。
          • parseControlCommand(String input):解析控制命令,调整设备状态。
          • createDevice(String deviceType):根据设备类型创建设备实例。

        此类用于解析输入命令,配置电路连接和设备状态。

        4. 主类

        Main

        • 方法
          • main(String[] args)
            • 创建 SmartHomeCircuitCommandParser 实例。
            • 从标准输入读取命令,调用相应方法解析。
            • 处理连接并输出设备状态。

        参考类图:

    时序图

  • 踩坑心得

    问题描述

    1. 设备状态管理

      • 窗帘开启比例的计算需要考虑所有灯的总光照强度
      • 需要正确处理电压不足时窗帘默认全开的情况
      • 并联电路的电压分配需要考虑电阻比例
      • 设备状态更新的顺序很重要
    2. 电路连接处理

      • 并联电路的等效电阻计算需要考虑所有支路
      • 串联和并联电路的嵌套关系需要正确识别
      • 需要正确处理T类和M类电路的IN/OUT引脚
      • 电压和电阻的计算需要考虑设备的特性
    3. 光照强度计算

      • 需要遍历所有灯具获取总光照强度
      • 白炽灯和日光灯的光照计算规则不同
      • 光照强度对窗帘开启比例的影响需要准确计算

    解决方法

    1. 设备状态管理

      这个问题的核心在于正确处理窗帘的状态更新逻辑,需要考虑电压条件和光照强度的综合影响。

    解决方法:

public class DeviceStateManager {
    private static final double MIN_VOLTAGE = 0.5;
    
    public void updateCurtainState(Curtain curtain, double voltage) {
        // 首先检查电压是否满足最低工作要求
        if (voltage < MIN_VOLTAGE) {
            curtain.setOpenRatio(1.0);  // 电压不足时默认全开
            return;
        }
        
        // 计算所有灯具的总光照
        double totalLux = calculateTotalLux();
        
        // 根据光照强度设置窗帘开启比例
        double openRatio = calculateOpenRatio(totalLux);
        curtain.setOpenRatio(openRatio);
    }
    
    // 计算总光照强度
    private double calculateTotalLux() {
        double totalLux = 0;
        for (Light light : lights) {
            if (light.isWorking()) {
                totalLux += light.getLux();
            }
        }
        return totalLux;
    }
}

实现要点:

  • 优先判断电压条件,确保电压不足时窗帘保持全开

  • 遍历所有工作状态的灯具计算总光照

  • 根据不同光照区间设置合适的开启比例

  • 注意状态更新的顺序,确保先更新灯具状态再更新窗帘

    1. 电路连接处理

      • 统一状态更新机制

        • SmartHomeCircuit 类的 processConnections 方法中,连接设备后立即更新设备的输入电压,并调用 updateState 方法以确保设备状态与连接关系一致。
        • 例如,开关设备在连接后会根据其状态设置输出电压,影响下游设备的状态更新:
          if (device1 instanceof ControlDevice && device2 instanceof ControlledDevice) {
              ((ControlledDevice) device2).updateState(((ControlDevice) device1).getOutputVoltage());
          }
          
      • 设备状态输出

        • displayStates 方法中,通过遍历 devices 映射,按照设备类型和编号排序输出状态。这确保了输出结果的可读性和一致性:
          devices.entrySet().stream()
              .sorted(Map.Entry.comparingByKey())
              .forEach(entry -> System.out.println(entry.getValue().getStatus()));
          
    2. 光照强度计算
      这个问题需要考虑不同类型灯具的光照特性,并准确计算其对窗帘的影响。

解决方法:

public class LightManager {
    public double calculateLightEffect(List<Light> lights) {
        double totalLux = 0;
        
        for (Light light : lights) {
            if (light instanceof IncandescentLight) {
                // 白炽灯光照计算
                totalLux += calculateIncandescentLux((IncandescentLight)light);
            } else if (light instanceof FluorescentLight) {
                // 日光灯光照计算
                totalLux += calculateFluorescentLux((FluorescentLight)light);
            }
        }
        
        return totalLux;
    }
    
    private double calculateCurtainRatio(double totalLux) {
        // 根据总光照确定窗帘开启比例
        if (totalLux < 50) return 1.0;
        if (totalLux < 100) return 0.8;
        if (totalLux < 200) return 0.6;
        return 0.4;
    }
}

实现要点:

  • 区分不同类型灯具的光照计算方式

  • 考虑灯具的工作状态和电压对光照的影响

  • 建立合理的光照强度与窗帘开启比例的对应关系

  • 确保光照计算的准确性和实时性

    • 改进与建议

      1. 改进设备连接的处理逻辑

        • 建议使用事件驱动机制:引入事件驱动的机制来处理设备连接和状态更新。可以在设备创建时注册一个事件,当所有设备创建完成并准备好处理连接时,触发一个事件来批量处理所有连接请求。这不仅可以使代码逻辑更清晰,还可以避免在处理连接时设备未创建的问题。
        • 实时连接反馈:在添加连接请求时,提供实时反馈机制。如果请求的设备尚未创建,可以立即记录警告信息,提示用户设备缺失。这可以帮助用户在输入阶段就发现并纠正错误。
      2. 优化设备状态更新的效率

        • 引入状态缓存:为了减少重复计算和提高效率,可以为设备状态引入缓存机制。在设备的状态更新方法中,只有当输入电压或控制参数发生变化时才更新状态。这可以减少不必要的计算,尤其是在复杂的电路中具有显著的性能提升。
        • 批量更新机制:对于涉及多个设备的状态更新,可以考虑引入批量更新机制。在完成所有连接处理后,统一触发所有设备的状态更新,而不是在每次连接时立即更新。这可以减少状态更新的次数,提高整体系统的响应速度。
  • 家居强电电路模拟程序-4

    • 题目分析

      本题要求设计一个智能家居强电电路模拟系统,旨在通过模拟控制设备和受控设备的行为,实现对智能家居电路的全面模拟和控制。相较于“家居强电电路模拟程序-1”,本次题目增加了如下功能和要求:

      1. 控制设备的拓展

        • 新增了分档调速器和连续调速器的模拟。分档调速器具有多个档位,每个档位输出不同的电压比例;连续调速器则通过档位参数按比例输出电压。这些设备的引入使得电路模拟更加复杂和逼真。
      2. 受控设备类型的增加

        • 本次迭代中增加了白炽灯、日光灯、吊扇和落地扇的模拟。每种设备都有特定的工作状态和性能参数(如亮度和转速),这些参数根据电压差变化。白炽灯和日光灯的亮度特性不同,吊扇和落地扇的转速特性也各异,这些细节丰富了电路模拟的内容。
      3. 电路信息的复杂化

        • 本次迭代引入了设备引脚的概念,要求处理每个电器的两个管脚的电压并输出。同时新增二极管元件,其电路特性为:正向导通,反向截止;当电流从左至右流过时,二极管导通”conduction”,电阻为0;电流从右至左流动时,二极管截止”cutoff”,电阻无穷大,相当于开关打开。
      4. 新增电路检测功能

        • 在电器在工作时,过大的电流会引起电器过热,从而烧坏电路。本次迭代,每个元器件都有最大电流的设置,当实时电流超过最大电流时,在该电器输出信息的最后加入提示“exceeding current limit error”本题各类电器的最大限定电流如下:开关20、分档调速器18、连续调速器18、白炽灯9、日光灯5、吊扇12、落地扇14、互斥开关20、受控窗帘12、二极管8。

      功能需求分析

      1. 设备信息输入

        • 每个设备通过标识符和编号进行标识,并通过引脚连接。设备信息直接包含在连接信息中,不单独输入。
      2. 电路连接信息输入

        • 连接信息以方括号表示,支持设备的串联和并联接入。串联电路和并联电路有各自的定义格式,要求按顺序输入。
      3. 电路连接管理

        • 支持串联电路(#T)和并联电路(#M)的组合
          处理复杂的嵌套关系(并联中包含并联)
          电压和电流的正确分配
          短路检测功能
      4. 电源接地标识

        • 电源(VCC)和接地(GND)的电压分别为220V和0V,未接线的引脚默认接地。
      5. 状态监控与输出

        • 设备状态实时监控,引脚电压值计算与显示,电流限制检测,按设备类型顺序输出状态信息,确保输出格式符合要求。

      实现要点

      1. 数据结构设计

        • 使用类和数据结构存储设备信息、连接信息和调节信息。需要设计合理的类层次结构来表示不同类型的设备及其特性。
      2. 输入处理

        • 解析输入字符串,处理设备和连接信息,确保输入格式正确并能正确解析复杂的电路结构。
      3. 设备状态更新和电路模拟

        • 根据连接关系和控制信息,模拟设备的工作状态和电路行为。确保设备状态的更新逻辑正确,尤其是在复杂的串联和并联电路中。
      4. 输出处理

        • 按照要求格式输出设备的状态或参数,确保输出结果的准确性和可读性。
    • 设计与分析

      • 整体逻辑

        1. 输入解析与初始化:

          • 主程序读取用户输入,解析电路连接结构和设备操作指令。
          • 根据输入,构建串联电路(SeriesCircuit)、并联电路(ParallelCircuit),以及各种控制设备和受控设备。
        2. 电路模型构建:

          • 每个设备或电路片段被抽象为一个对象,统一存储在Circuit类中。
          • 支持复杂电路结构,包括串联和并联的嵌套关系。
        3. 状态更新:

          • 通过设备之间的连接关系,传递电压、电流,更新设备状态(如开关状态、灯亮度、风扇转速等)。
        4. 电路计算:

          • 按照串联与并联的计算规则,确定总电阻、电压分配以及电路中是否存在短路或开路。
        5. 指令执行与输出:

          • 根据用户输入的指令,执行设备操作(如开关切换、调速器调节等)。
          • 输出所有设备的状态,包括电压、电流和可能的错误提示。

      • 源码分析

        1. 主程序(Main类)

        主要功能:

        • 负责解析用户输入,初始化电路结构和设备。
        • 调用电路模型(Circuit)的方法,进行电路仿真和状态输出。

        逻辑分析:

        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            List<String> commands = new ArrayList<>();
        
            while (true) {
                String line = scanner.nextLine().trim();
                if ("end".equalsIgnoreCase(line)) break;
                
                // 串联电路解析
                if (line.startsWith("#T")) { 
                    ...
                }
        
                // 并联电路解析
                if (line.startsWith("#M")) { 
                    ...
                }
        
                // 设备控制指令解析
                else if (line.startsWith("#K") || line.startsWith("#H") || line.startsWith("#L") || line.startsWith("#F")) {
                    commands.add(line);
                }
            }
        
            parseDevices(); // 解析设备
            circuit.executeCommands(commands); // 执行指令
            circuit.establishConnections(Circuits, parallelCircuits); // 建立电路连接
            circuit.calculateCircuitVoltage(); // 计算电路电压
            circuit.printStatus(); // 输出状态
        }
        

        解析模块:

        • 按照输入的标识符解析不同类型的电路(#T代表串联,#M代表并联)和设备。
        • 将解析后的设备加入全局SimulationDevices列表。

        2. 设备抽象与继承体系

        所有设备都继承自Device基类,基类定义了通用属性和方法,各设备根据其特性实现具体逻辑。

        核心属性:

        abstract class Device {
            protected String name;          // 设备名称
            protected double inputVoltage;  // 输入电压
            protected double outputVoltage; // 输出电压
            protected double current;       // 电流
            protected double LimteCurrent;  // 最大电流限制
            protected String inputPin;      // 输入引脚
            protected String outputPin;     // 输出引脚
        
            public void updateState() { }   // 状态更新方法(抽象)
        }
        

        控制设备(ControlDevice:

        • 定义了setCurrent()方法,用于设置电流。
        • 不同控制设备(如开关、调速器)实现了各自的状态更新逻辑。

        示例:开关设备(Switch:

        class Switch extends ControlDevice {
            protected boolean status = false; // 开关状态
        
            @Override
            public void updateState() {
                this.outputVoltage = this.status ? inputVoltage : 0;
            }
        
            public void toggleStatus() {
                this.status = !this.status; // 切换开关状态
            }
        }
        

        受控设备(ControlledDevice:

        • 定义了dianshicha(电位差)和resistance(电阻)。
        • 更新状态时需要计算电流,检测是否超出限制。

        示例:灯(Light:

        abstract class Light extends ControlledDevice {
            private int brightness; // 亮度
        
            @Override
            public void updateState() {
                this.brightness = (int)(inputVoltage / 220.0); // 假设220V为最大电压
            }
        }
        

        3. 电路模型(Circuit类)

        功能:

        • 管理所有设备及其连接关系。
        • 提供电路计算逻辑,包括电压分配、总电阻计算,以及短路和开路检测。

        核心方法:

        1. 设备添加:
        public void addDevice(Device device) {
            if (!devices.containsKey(device.name)) {
                devices.put(device.name, device);
            }
        }
        
        1. 连接管理:
        public void establishConnections(Map<String, List<String>> circuits, Map<String, List<String>> parallelCircuits) {
            // 遍历所有串联和并联电路,建立连接
            ...
        }
        
        1. 电压计算:
        public void calculateCircuitVoltage() {
            SeriesCircuit maincircuit = (SeriesCircuit)devices.get(Main.Maincircuit);
        
            if (maincircuit.isDuanlu) { 
                System.out.println("short circuit error"); 
                return;
            }
        
            maincircuit.setInputVoltage(220.0);
            maincircuit.setDianshicha(220.0);
        }
        

        4. 电路实现

        串联电路(SeriesCircuit:

        • 继承SimulationCircuit
        • 计算总电阻、检查是否存在短路或开路。
        • 实现电压分配逻辑。
        public void calculateSeriesResistance() {
            for (Device device : SmCircuit.values()) {
                if (device instanceof ControlledDevice) {
                    this.resistance += ((ControlledDevice) device).getResistance();
                }
            }
        }
        

        并联电路(ParallelCircuit:

        • 计算总电阻:
        public void calculateParallelResistance() {
            double totalResistance = 0;
        
            for (SeriesCircuit subCircuit : subCircuits) {
                double subResistance = subCircuit.getresistance();
                if (subResistance != 0) {
                    totalResistance += 1.0 / subResistance;
                }
            }
            this.resistance = totalResistance == 0 ? 0 : 1.0 / totalResistance;
        }
        

        5. 异常处理

        短路检测:

        • 串联电路检查是否所有设备均导通。
        • 并联电路检查是否所有支路均开路。

        电流超限检测:

        • ControlledDeviceControlDevice中实现getLimteMSG()方法。
        • 输出设备状态时,提示超限错误。

        6. 状态输出

        通过printStatus()方法,按设备类型输出状态信息,包含电压、电流及异常提示。

        示例:

        public void printStatus() {
            devices.values().stream()
                   .filter(device -> device instanceof Switch)
                   .forEach(device -> System.out.println(device));
        }
        

以下是参考类图:(由于前三次的代码逻辑并不实用,最后一次的代码推翻了前面所有代码从头开始,类名以及方法名不太一样)

- ###时序图

  • 踩坑心得

    问题描述

    1. 并联电路逻辑设计的复杂性

      • 在智能家居电路系统中,并联电路的设计尤为复杂,因为并联电路中各设备的电压相等,但电流分配不同。处理并联电路的逻辑需要确保所有设备都能正确接收到相同的电压,而这在解析和实现时会遇到挑战,尤其是在设备连接和电压计算过程中。
    2. 并联电路中设备电压计算的挑战

      • 并联电路中,每个设备的电压应与总电压相等,但由于设备的电阻和状态不同,如何在程序中准确计算和分配电压是一个难点。错误的电压计算可能导致设备状态更新不正确,进而影响整个电路的模拟结果。

    解决方法

    1. 并联电路逻辑设计的解决方法

      • 使用专门的电路类

        • 在系统中设计 ParallelCircuit 类来专门处理并联电路的逻辑。通过这个类,可以将并联电路的设备视为一个整体,统一管理其电压分配。
        • 例如,在 ParallelCircuit 类中,定义一个方法 calculateVoltageDistribution() 来确保所有设备接收到相同的电压:
          public void calculateVoltageDistribution(double totalVoltage) {
              for (Device device : devices) {
                  device.updateState(totalVoltage);
              }
          }
          
      • 连接请求的延迟处理

        • CommandParser 类中,解析并联电路的命令时,先将连接请求存储起来,而不是立即处理。这种方式确保在所有设备创建完毕后,能够正确地建立并联电路的连接关系。
    2. 并联电路中设备电压计算的解决方法

      • 统一电压更新机制

        • SmartHomeCircuit 类中,设计一个统一的机制来更新并联电路中每个设备的电压。在 processConnections 方法中,识别并联电路后,调用 ParallelCircuit.calculateVoltageDistribution() 方法分配电压。
        • 例如:
          if (isParallelCircuit(connection)) {
              parallelCircuit.calculateVoltageDistribution(totalVoltage);
          }
          
      • 确保电压一致性

        • displayStates 方法中,输出设备状态时验证电压的一致性,确保并联电路中的所有设备电压相同。这可以通过在遍历设备状态时检查电压是否与预期一致来实现:
          devices.entrySet().stream()
              .filter(entry -> entry.getValue() instanceof ParallelDevice)
              .forEach(entry -> {
                  double expectedVoltage = totalVoltage; // 假设并联电路总电压
                  assert entry.getValue().getVoltage() == expectedVoltage;
                  System.out.println(entry.getValue().getStatus());
              });
          
  • 改进与建议

    1. 使用单元测试覆盖关键逻辑

      • 为电路系统的关键部分编写单元测试,特别是设备连接、状态更新和电压计算等核心逻辑。通过使用测试驱动开发(TDD)的方法,可以确保在代码改动或重构时不会引入新的错误。使用测试框架(如 JUnit)编写自动化测试用例,以验证每个模块的功能和边界条件。
    2. 优化数据结构选择

      • 考虑使用更高效的数据结构来管理设备和连接。例如,可以使用 HashMap 来存储设备以便快速检索,同时使用 Graph 数据结构来表示设备之间的连接关系。这不仅提高了连接和状态更新的效率,还能更方便地实现复杂的电路拓扑操作(如循环检测和路径查找)。
  • 总结

    在本阶段的学习中,通过设计和实现复杂的智能家居强电电路模拟系统,我学到了许多关于软件设计、数据结构、算法实现以及系统模拟的知识。

    通过智能家居强电电路模拟系统的持续迭代开发,我对复杂电路模拟和物联网设备控制有了更深入的理解。从最初的基础电路模拟,发展到引入互斥开关、分档调速器、连续调速器等多种设备,再到增加二极管、管脚电压显示、短路检测和电流限制等高级功能,系统的复杂性和真实性不断提升。在实现过程中,我不仅强化了对设备特性和电路行为的细节模拟,还通过并联电路串联和嵌套场景的处理提升了系统的功能完整性。特别是在电压计算、性能参数动态更新、复杂连接结构处理等方面,系统展现出更高的精确性和可靠性。这次开发深化了我对数据结构和算法的应用能力,提升了电路模型抽象和代码结构优化的能力。通过统一的状态输出格式和错误提示机制,系统的易用性和鲁棒性得到显著改善。

    在当前阶段的学习中,我掌握了面向对象编程的核心概念,包括封装、继承和多态,并能够熟练运用这些概念来构建模块化的代码结构。同时,通过处理复杂的电路连接关系,我加强了对数据结构(如图、树等)的理解和应用能力。在异常处理、输入验证和状态管理等方面的实践,也让我对软件工程的基本原则有了更深的认识。

    展望未来的学习规划,我计划在以下几个方面继续深化:

    1. 深入学习设计模式,提高代码的可维护性和可扩展性
    2. 加强对并发编程的理解,为处理更复杂的实时系统做准备
    3. 学习性能优化技术,提高系统在处理大规模数据时的效率
    4. 探索自动化测试和持续集成的实践,提高代码质量和开发效率

    对于课程的改进建议,建议在现有的项目驱动学习模式基础上,增加更多实际项目案例的讲解和分析,并适当增加团队协作项目的比重。同时可以考虑设置阶段性的代码评审环节,让学生之间互相学习和交流,培养代码质量意识和团队协作能力。在教学进度安排上,建议在基础知识讲解和实践项目之间保持更好的平衡,确保学生在掌握理论知识的同时,有充足的时间进行项目实践和优化改进。此外,可以考虑邀请业界专家进行专题讲座,分享实际项目经验和行业动态,帮助学生更好地理解理论知识在实际工作中的应用。

  • 学期总结

    在本学期对Java课程的学习过程中我从最基础的语法概念开始,逐步掌握了面向对象编程的核心思想,包括类与对象、继承与多态、接口与抽象类等重要概念,并通过答题判题程序和智能家居强电电路模拟系统的开发实践深化了对这些知识的理解。随着学习的深入,我理解了面向对象编程的核心思想,学会了如何定义类、创建对象,以及理解封装、继承和多态这些重要概念。通过PTA大作业练习和简单项目实践,我掌握了方法的定义和调用、构造函数的使用,以及基本的异常处理机制,同时培养了规范的代码编写习惯,如正确的代码缩进和添加必要的注释说明。虽然在学习过程中遇到了不少困难,特别是在理解抽象概念和解决编程错误时,但通过老师的耐心指导和同学间的互相帮助,我逐渐建立起了编程的思维方式,能够独立完成简单的Java程序开发,为今后深入学习Java打下了良好的基础。

posted @ 2024-12-28 18:00  千世绪川  阅读(52)  评论(0)    收藏  举报