原始代码:
if (ChannelTypeEnum.CHANNEL_TEXT.getCode().equals(channelType) || ChannelTypeEnum.CHANNEL_VOICE.getCode().equals(channelType)) {
smsSendTask(currentChannelParam, sendStrategy, mixId, channelBatchNo);
} else if (ChannelTypeEnum.CHANNEL_FIVE_G.getCode().equals(channelType)) {
fiveGSendTask(currentChannelParam, sendStrategy, mixId, channelBatchNo);
}
public void smsSendTask(String currentChannelParam, Integer sendStrategy, Long mixId, String channelBatchNo) throws Exception {
//转换对象
SmsSendTaskVo smsSendTaskVo = new SmsSendTaskVo();
smsSendTaskVo = new ObjectMapper().readValue(currentChannelParam, SmsSendTaskVo.class);
smsSendTaskVo.setSendStrategy(sendStrategy);
smsSendTaskVo.setMixSendId(mixId);
smsSendTaskVo.setChannelBatchNo(channelBatchNo);
smsSendTaskVo.setIsCurrentChannel(StrategyServiceConstant.TRUE);
}
public void fiveGSendTask(String currentChannelParam, Integer sendStrategy, Long mixId, String channelBatchNo) throws Exception {
//转换对象
FiveGSendTaskDto fiveGSendTaskDto = new FiveGSendTaskDto();
fiveGSendTaskDto = new ObjectMapper().readValue(currentChannelParam, FiveGSendTaskDto.class);
fiveGSendTaskDto.setSendStrategy(sendStrategy);
fiveGSendTaskDto.setMixSendId(mixId);
fiveGSendTaskDto.setChannelBatchNo(channelBatchNo);
fiveGSendTaskDto.setIsCurrentChannel(StrategyServiceConstant.TRUE);
}
方案一:
可以将这两个方法合并为一个通用的方法,可以接收任意类型的对象,并执行相同的逻辑。下面是一个可能的实现:
public void sendTask(String currentChannelParam, Object sendTaskObject, Integer sendStrategy, Long mixId, String channelBatchNo) throws Exception {
//转换对象
try {
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
Object taskObject = mapper.readValue(currentChannelParam, sendTaskObject.getClass());
//设置公共属性
Method setSendStrategyMethod = sendTaskObject.getClass().getMethod("setSendStrategy", Integer.class);
setSendStrategyMethod.invoke(taskObject, sendStrategy);
Method setMixSendIdMethod = sendTaskObject.getClass().getMethod("setMixSendId", Long.class);
setMixSendIdMethod.invoke(taskObject, mixId);
Method setChannelBatchNoMethod = sendTaskObject.getClass().getMethod("setChannelBatchNo", String.class);
setChannelBatchNoMethod.invoke(taskObject, channelBatchNo);
Method setIsCurrentChannelMethod = sendTaskObject.getClass().getMethod("setIsCurrentChannel", Integer.class);
setIsCurrentChannelMethod.invoke(taskObject, StrategyServiceConstant.TRUE);
//执行业务逻辑
if (taskObject instanceof SmsSendTaskVo) {
smsSendTask((SmsSendTaskVo) taskObject);
} else if (taskObject instanceof FiveGSendTaskDto) {
fiveGSendTask((FiveGSendTaskDto) taskObject);
}
} catch (Exception e) {
log.error("异常数据={}", currentChannelParam);
log.error(e.getMessage(), e);
throw new IllegalPropertySetDataException("当前渠道参数" + ParamStatusEnum.UN_SUPPORT_PROPERTIES.getDescription());
}
}
private void smsSendTask(SmsSendTaskVo smsSendTaskVo) {
//执行接口调用逻辑
//...
}
private void fiveGSendTask(FiveGSendTaskDto fiveGSendTaskDto) {
//执行接口调用逻辑
//...
}
这个 sendTask 方法接收了五个参数,第一个是 currentChannelParam,表示当前渠道的参数(JSON格式),第二个是 sendTaskObject,表示发送任务对象的实例,第三个是 sendStrategy,表示发送策略,第四个是 mixId,表示混合发送任务ID,第五个是 channelBatchNo,表示其他渠道批次号。
在方法内部,我们首先使用 ObjectMapper 将 currentChannelParam 转换为指定类型的对象。然后,我们使用反射设置公共属性,这些属性对于所有发送任务对象都是相同的。最后,我们根据对象的类型分别调用相应的业务逻辑方法。
注意,在反射调用方法时,我们使用了 getMethod 方法获取方法的实例,然后使用 invoke 方法调用该方法。因为 setIsCurrentChannel 方法的参数类型是 Integer,而不是 int,所以我们需要将常量 StrategyServiceConstant.TRUE 包装为一个 Integer 对象。
方案二:
你可以通过将对象类型作为参数传递给一个单独的方法来避免重复的代码。在这种情况下,你可以创建一个通用的方法来处理不同类型的对象,并且根据传入的对象类型进行相应的操作。下面是一个示例代码:
public void sendTask(String currentChannelParam, Integer sendStrategy, Long mixId, String channelBatchNo, Object taskObject) throws Exception {
if (taskObject instanceof SmsSendTaskVo) {
SmsSendTaskVo smsSendTaskVo = (SmsSendTaskVo) taskObject;
smsSendTaskVo = new ObjectMapper().readValue(currentChannelParam, SmsSendTaskVo.class);
smsSendTaskVo.setSendStrategy(sendStrategy);
smsSendTaskVo.setMixSendId(mixId);
smsSendTaskVo.setChannelBatchNo(channelBatchNo);
smsSendTaskVo.setIsCurrentChannel(StrategyServiceConstant.TRUE);
} else if (taskObject instanceof FiveGSendTaskDto) {
FiveGSendTaskDto fiveGSendTaskDto = (FiveGSendTaskDto) taskObject;
fiveGSendTaskDto = new ObjectMapper().readValue(currentChannelParam, FiveGSendTaskDto.class);
fiveGSendTaskDto.setSendStrategy(sendStrategy);
fiveGSendTaskDto.setMixSendId(mixId);
fiveGSendTaskDto.setChannelBatchNo(channelBatchNo);
fiveGSendTaskDto.setIsCurrentChannel(StrategyServiceConstant.TRUE);
} else {
throw new IllegalArgumentException("Unsupported task object type");
}
}
在这个示例中,我创建了一个名为sendTask的通用方法,它接受一个taskObject参数作为要处理的对象类型。通过使用instanceof运算符,我们可以确定传入的对象类型,并且在方法内部对不同类型的对象进行相应的操作。
当调用这个通用方法时,你只需要传入相应的对象类型作为参数,比如:
sendTask(currentChannelParam, sendStrategy, mixId, channelBatchNo, new SmsSendTaskVo());
sendTask(currentChannelParam, sendStrategy, mixId, channelBatchNo, new FiveGSendTaskDto());
通过这种方法,你可以避免重复的代码,并且实现对不同对象类型的统一处理。