策略模式+Spring配置类优化多if..else思路
图示#
1. 现状#
场景: 假设设备上报不同类型的消息,我们要对不同类型的消息做不同的处理。如果我们通过if..else的方式处理的话会显得比较冗余。
例如:
if("alarmEvent".equals(msg)){
// 处理告警消息逻辑 ...
}else if("deviceBase".equals(msg)){
// 处理设备上报的基本信息 ...
}else if("heartBeat".equals(msg)){
// 处理设备心跳消息 ...
}else {
// ...
}
2. 消息处理Handler#
那么对于不同消息的不同的处理逻辑我们可以单独放在一个实现类中,这些类有着相同的行为,所以我们可以定义一个接口:
public interface MessageHandler<T>{
T invoke(String bizUpMessage); // 处理接收到的消息
String getName();
String getIdentification(); // 获取消息标志
}
针对于不同的消息,我们可以有各自的实现
实现类1:
@Component
public class DeviceBaseInfoHandler implements MessageHandler<String> {
@Override
public String invoke(String bizUpMessage) {
// 处理设备上报的基本信息 ...
return "";
}
@Override
public String getName() {
return "";
}
@Override
public String getIdentification() {
return "DeviceBaseInfoRequest";
}
}
实现类2:
@Component
public class AlarmEventHandler implements MessageHandler<String>{
@Override
public String invoke(String bizUpMessage) {
// 处理告警信息 ...
return null;
}
@Override
public String getName() {
return "";
}
@Override
public String getIdentification() {
return "AlarmEventRequest";
}
}
3. Handler注册处#
我们可以将上一步的消息处理对象,根据消息的标志(Identification)不同,将消息放在一个Map中:
public class MessageHandlerRegisty {
private Map<String, List<MessageHandler>> registerMap = new HashMap<>();
// 注册各种 handler
public void regist(String identification, MessageHandler handler){
if(this.contains(identification)){
get(identification).add(handler);
} else {
List<MessageHandler> list = new ArrayList<>();
list.add(handler);
registerMap.put(identification, list);
}
}
public boolean contains(String identification){
return registerMap.containsKey(identification);
}
public List<MessageHandler> get(String identification){
return registerMap.get(identification);
}
}
4. 消息接收Service#
消息接收接口
public interface IMessageService {
void messageReceived(String bizUpMessage); // 接收消息
}
5. 消息接收ServiceImpl#
消息接收实现类
public class MessageServiceImpl implements IMessageService{
public MessageHandlerRegisty registy;
// 线程池
public ExecutorService executorService = new ThreadPoolExecutor(3, 10, 15, TimeUnit.MINUTES, new LinkedBlockingQueue(1000), new LogdDiscardPolicy());
public void messageReceived(String bizUpMessage){
// 获取消息的标志Identification
String identification = extractIdentification(bizUpMessage);
if(StringUtils.isBlank(identification)){
return;
}
if(!registy.contains(identification)){
return;
}
for(MessageHandler handler : registy.get(identification)){
execute(handler, bizUpMessage); // 多线程处理消息
}
}
public MessageHandlerRegisty getRegisty() {
return registy;
}
public void setRegisty(MessageHandlerRegisty registy) {
this.registy = registy;
}
private void execute(MessageHandler handler, String bizUpMessage){
executorService.submit(new IotMessageTask(handler, bizUpMessage));
}
public final class LogdDiscardPolicy extends ThreadPoolExecutor.DiscardPolicy {
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
log.warn("MessageService pool is full !!!!!!!!");
}
}
final class IotMessageTask implements Runnable {
private MessageHandler handler;
private String bizUpMessage;
public IotMessageTask(MessageHandler handler, String bizUpMessage){
this.handler = handler;
this.bizUpMessage = bizUpMessage;
}
@Override
public void run() {
try {
Stopwatch stopwatch = Stopwatch.createStarted();
handler.invoke(bizUpMessage);
stopwatch = stopwatch.stop();
long cost = stopwatch.elapsed(TimeUnit.MICROSECONDS);
logTime(cost);
}catch (Exception e){
log.error("handler execute error - ", e);
}
}
private void logTime(long cost){
if(cost > 50){
log.warn(" handler -> {}, cost too much -> {}", handler.getName(), cost);
} else {
log.info("handler -> {}, cost -> {}", handler.getName(), cost);
}
}
}
}
6. 将MessageServiceImpl对象配置到spring容器#
@Configuration
public class ManagerConfig {
@Bean
public IMessageService messageService(){
MessageServiceImpl messageService = new MessageServiceImpl();
messageService.setRegisty(buildRegisty());
return messageService;
}
// 消息处理handler
@Autowired
private DeviceBaseInfoHandler deviceBaseInfoHandler;
@Autowired
private AlarmEventHandler alarmEventHandler;
private MessageHandlerRegisty buildRegisty(){
MessageHandlerRegisty registy = new MessageHandlerRegisty();
registy.regist(deviceBaseInfoHandler.getIdentification(), deviceBaseInfoHandler);
registy.regist(alarmEventHandler.getIdentification(),alarmEventHandler);
return registy;
}
}
作者:Charlton
出处:https://www.cnblogs.com/charlton/p/17586887.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!