用枚举干掉switch
原代码
消息类型的枚举:
public enum WxocTemplateMessageTypeEnum {
/**
* 电话访谈活动开始之前
*/
BEFORE_TELEPHONE_INTERVIEW_ACTIVITY_START,
/**
* 路演活动开始之前
*/
BEFORE_ROAD_SHOW_ACTIVITY_START,
/**
* 会议结束通知
*/
ACTIVITY_END,
/**
* 会议取消通知
*/
ACTIVITY_CANCEL,
;
}
消息控制器发送消息的方法:
private void sendWxoxTemplateMessage(MessageTypeEnum type,ISystemMessageConsumerService messageConsumer,String body){
log.debug("消息消费-发送公众号模版消息处理开始");
if(type.isSendWxoxTemplateMessage()){
//获取消息模版类型
WxocTemplateMessageTypeEnum templateMessageTypeEnum = messageConsumer.getWxocTemplateMessageTypeEnum(body);
if(templateMessageTypeEnum==null){
log.debug("消息消费-发送公众号模版消息-未知的消息类型");
return ;
}
WxocTemplateMessageForm templateMessageForm = messageConsumer.generateWxocTemplateMessageForm(body);
if(templateMessageForm==null){
log.debug("消息消费-发送公众号模版消息-生成消息模版失败");
return ;
}
Integer wxocUserId = messageConsumer.getWxocUserId(body);
if(wxocUserId==null){
log.debug("消息消费-发送公众号模版消息-没有有效的微信公众号用户");
return ;
}
switch (templateMessageTypeEnum){
case BEFORE_TELEPHONE_INTERVIEW_ACTIVITY_START:
innerProjectWxocApi.sendBeforeTelephoneInterviewTemplateMessage(wxocUserId,templateMessageForm);
break;
case BEFORE_ROAD_SHOW_ACTIVITY_START:
innerProjectWxocApi.sendBeforeRoadShowActivityStartTemplateMessage(wxocUserId,templateMessageForm);
break;
case ACTIVITY_CANCEL:
innerProjectWxocApi.sendActivityCancelTemplateMessage(wxocUserId,templateMessageForm);
break;
case ACTIVITY_END:
innerProjectWxocApi.sendActivityEndTemplateMessage(wxocUserId,templateMessageForm);
break;
case RECEIPT_OF_ACCOUNT:
innerProjectWxocApi.sendReceiptOfAccountTemplateMessage(wxocUserId,templateMessageForm);
break;
default:
}
}
log.debug("消息消费-发送公众号模版消息处理结束");
}
原代码存在问题:
- 在增加新的消息类型时,需要同步修改消息发送控制器,在switch语句里增加新的case子语句。
- 两边的修改不是同步的,容易导致修改遗漏,比如只修改了消息的类型枚举,而没有修改消息的发送控制器。
优化后的代码
消息类型的枚举:
public enum WxocTemplateMessageTypeEnum {
/**
* 电话访谈活动开始之前
*/
BEFORE_TELEPHONE_INTERVIEW_ACTIVITY_START(
(api,wxocUserId,form)->api.sendBeforeTelephoneInterviewTemplateMessage(wxocUserId,form)),
/**
* 路演活动开始之前
*/
BEFORE_ROAD_SHOW_ACTIVITY_START(
(api,wxocUserId,form)->api.sendBeforeRoadShowActivityStartTemplateMessage(wxocUserId,form)),
/**
* 会议结束通知
*/
ACTIVITY_END(
(api,wxocUserId,form)->api.sendActivityEndTemplateMessage(wxocUserId,form)),
/**
* 会议取消通知
*/
ACTIVITY_CANCEL(
(api,wxocUserId,form)->api.sendActivityCancelTemplateMessage(wxocUserId,form)),
/**
* 收款到账通知
*/
RECEIPT_OF_ACCOUNT(
(api,wxocUserId,form)->api.sendReceiptOfAccountTemplateMessage(wxocUserId,form)),
;
/**
* 消息发送器
*/
private SendMessageHandler sendMessageHandler;
private WxocTemplateMessageTypeEnum(SendMessageHandler handler){
this.sendMessageHandler = handler;
}
/**
* 发送消息
* @param innerProjectWxocApi
* @param wxocUserId
* @param templateMessageForm
* @return void
*/
public void sendMessage(InnerProjectWxocApi innerProjectWxocApi, Integer wxocUserId,WxocTemplateMessageForm templateMessageForm){
this.sendMessageHandler.sendMessage(innerProjectWxocApi,wxocUserId,templateMessageForm);
}
/**
* 发送消息处理器接口
*/
private interface SendMessageHandler{
/**
* 发送消息的方法
* @param innerProjectWxocApi
* @param wxocUserId
* @param templateMessageForm
* @return void
*/
void sendMessage(InnerProjectWxocApi innerProjectWxocApi, Integer wxocUserId,WxocTemplateMessageForm templateMessageForm);
}
}
消息控制器发送消息的方法:
private void sendWxoxTemplateMessage(MessageTypeEnum type,ISystemMessageConsumerService messageConsumer
,String body){
log.debug("消息消费-发送公众号模版消息处理开始");
if(type.isSendWxoxTemplateMessage()){
//获取消息模版类型
WxocTemplateMessageTypeEnum templateMessageTypeEnum = messageConsumer.getWxocTemplateMessageTypeEnum(body);
if(templateMessageTypeEnum==null){
log.debug("消息消费-发送公众号模版消息-未知的消息类型");
return ;
}
WxocTemplateMessageForm templateMessageForm = messageConsumer.generateWxocTemplateMessageForm(body);
if(templateMessageForm==null){
log.debug("消息消费-发送公众号模版消息-生成消息模版失败");
return ;
}
Integer wxocUserId = messageConsumer.getWxocUserId(body);
if(wxocUserId==null){
log.debug("消息消费-发送公众号模版消息-没有有效的微信公众号用户");
return ;
}
templateMessageTypeEnum.sendMessage(innerProjectWxocApi,wxocUserId,templateMessageForm);
}
log.debug("消息消费-发送公众号模版消息处理结束");
}
优化说明:
- 定义了一个
SendMessageHandler
接口,该接口只提供了一个sendMessage
的方法,按照Java语法,只有一个方法的接口称之为函数接口。- 为什么要定义函数接口?,因为Java自带的函数接口没有支持传3个参数的,所以需要自己定义一个。
- 在枚举的构造函数里增加了
SendMessageHandler
接口实现的参数,用于指定每个枚举的消息具体的消息发送处理方法。- 构造枚举时,指定当前枚举的实际执行的
api
的具体的方法。- 为每个枚举提供一个发送消息的方法,用于调用
SendMessageHandler
的实现。- 消息控制器只需要拿到本次待发送消息的枚举,直接调用枚举的发送消息的方法,传入对应的参数即可。