设备数据解析设计模式
最佳实践:采用 策略模式(Strategy Pattern) + 工厂模式(Factory Pattern) 组合,实现高扩展、高可维护的多设备数据解析。
1. 策略模式
封装不同设备的解析算法
// 策略接口:所有设备类型的数据解析器都必须实现
public interface DeviceDataParseStrategy {
/**
* 解析设备上报的原始字节数据
* @param rawData 设备上报的原始字节数组
* @param deviceId 设备ID(卡号)
* @return 统一的数据对象
*/
DeviceDataDTO parse(byte[] rawData, String deviceId);
}
// 示例:设备类型A的解析策略
@Component("typeADataParseStrategy")
public class TypeADataParseStrategy implements DeviceDataParseStrategy {
@Override
public DeviceDataDTO parse(byte[] rawData, String deviceId) {
DeviceDataDTO dto = new DeviceDataDTO();
dto.setDeviceId(deviceId);
dto.setReceiveTime(DateUtil.now()); // Hutool 获取当前时间
// 类型A专属解析逻辑(示例)
// 假设协议:偏移0-1字节为亮度,2-3字节为电压(0.1V单位)
int brightness = ByteUtil.bytesToShort(rawData, 0); // Hutool 字节工具
double voltage = ByteUtil.bytesToShort(rawData, 2) / 10.0;
dto.getExtData().put("brightness", brightness);
dto.getExtData().put("voltage", voltage);
// 可继续解析电流、故障码等...
return dto;
}
}
// 示例:设备类型B的解析策略(协议完全不同)
@Component("typeBDataParseStrategy")
public class TypeBDataParseStrategy implements DeviceDataParseStrategy {
@Override
public DeviceDataDTO parse(byte[] rawData, String deviceId) {
DeviceDataDTO dto = new DeviceDataDTO();
dto.setDeviceId(deviceId);
dto.setReceiveTime(DateUtil.now());
// 类型B专属解析逻辑(示例)
// 假设使用IEEE754浮点数表示开关状态和温度
int status = rawData[0] & 0xFF;
float temperature = ByteUtil.bytesToFloat(rawData, 1);
dto.getExtData().put("switchStatus", status == 1 ? "ON" : "OFF");
dto.getExtData().put("temperature", temperature);
return dto;
}
}
2. 工厂模式
根据设备类型动态获取解析策略
@Service
public class DeviceDataParseFactory {
// Spring 自动注入所有解析策略实现,key 为 Bean 名称
private final Map<String, DeviceDataParseStrategy> strategyMap;
public DeviceDataParseFactory(Map<String, DeviceDataParseStrategy> strategyMap) {
this.strategyMap = strategyMap;
}
public DeviceDataParseStrategy getStrategy(String deviceType) {
// 使用 Hutool 优化命名规则
String beanName = StrUtil.lowerFirst(deviceType) + "DataParseStrategy";
DeviceDataParseStrategy strategy = strategyMap.get(beanName);
if (strategy == null) {
throw new UnsupportedOperationException("不支持的设备类型解析: " + deviceType);
}
return strategy;
}
}
- 在 Service 层统一调用(推荐方式)
@Service
public class DeviceDataService {
@Autowired
private DeviceDataParseFactory parseFactory;
/**
* 处理设备上报数据
* @param deviceType 设备类型
* @param rawData 原始字节数据
* @param deviceId 设备ID
*/
public void handleUploadData(String deviceType, byte[] rawData, String deviceId) {
// 1. 使用工厂 + 策略动态解析
// 通过工厂根据设备类型获取对应的解析策略对象
// 体现了工厂模式:运行时自动选择正确实现
// 体现了策略模式:不同设备使用完全独立的解析算法
DeviceDataParseStrategy strategy = parseFactory.getStrategy(deviceType);
// 调用策略的 parse 方法执行专属解析逻辑
// 返回统一DTO,便于后续统一存储、展示、告警等业务处理
DeviceDataDTO dto = strategy.parse(rawData, deviceId);
// 2. 统一业务处理(存储、告警、统计等)
// saveToDatabase(dto);
// checkAlarm(dto);
log.info("设备数据解析成功 deviceId={} type={} data={}", deviceId, deviceType, dto.getExtData());
}
}
如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ ~


浙公网安备 33010602011771号