设计模式——责任链模式实战,优雅处理Kafka消息

首页 编程分享 PHP丨JAVA丨OTHER 正文

KD 转载 编程分享 2025-12-20 22:15:23

简介 一、业务背景 Kafka接收消息,需要A,B,C...多种策略做处理,再通过http请求发送给下游。多种策略混在一起很难维护,通过责任链模式把每种策略的代码收敛到自己的Handler中 二、具体设计


一、业务背景

Kafka接收消息,需要A,B,C...多种策略做处理,再通过http请求发送给下游。多种策略混在一起很难维护,通过责任链模式把每种策略的代码收敛到自己的Handler中

二、具体设计

classDiagram
Handler <|-- StrategyAHandler
Handler <|-- StrategyBHandler
Handler <|-- UploadHandler
Handler: +void handleUserData(UserContext, HandlerChain)
Handler: +void handleOrderData(OrderContext, HandlerChain)
class StrategyAHandler {
+void handleUserData(UserContext, HandlerChain)
+void handleOrderData(OrderContext, HandlerChain)
}
class StrategyBHandler {
+void handleUserData(UserContext, HandlerChain)
+void handleOrderData(OrderContext, HandlerChain)
}
class UploadHandler {
+void handleUserData(UserContext, HandlerChain)
+void handleOrderData(OrderContext, HandlerChain)
}
HandlerChain o--o Handler
class HandlerChain {
+List~Handler~ chain
+void doHandle(AbstractContext context)
}
HandlerChain --> AbstractContext
class AbstractContext {
+JSONObject param
+int position
}
AbstractContext <|-- UserContext
AbstractContext <|-- OrderContext
class UserContext {
+UserInfo userInfo
}
class OrderContext {
+OrderInfo orderInfo
}

三、代码实现

1.HandlerChain类

public class HandlerChain {

    List<Handler> chain;
    
    public HandlerChain() {
        chain = new ArrayList<>();
    }
    
    public void doHandle(AbstractContext context) {
        // 截止条件
        if (context.getPosition() >= chain.size()) {
            return;
        }
        // 获取当前要执行的handler
        Handler handler = chain.get(context.getPosition());
        // 移动到下一个要执行的handler位置
        context.setPosition(context.getPosition() + 1);
        // 利用Context类的多态,判断执行的具体方法
        if (context instanceof UserContext) {
            handler.handleUserData((UserContext) context, this);
        } else if (context instanceof OrderContext) {
            handler.handleOrderData((OrderContext) context, this);
        }
    }
    
    public void addHandler(Handler handler) {
        chain.add(hander);
    }

}

2.Handler类

  • Handler接口:定义需要处理的消息
public interface Handler {
    // 处理用户数据消息
    void handleUserData(UserContext userContext, HandlerChain chain);
    // 处理订单数据消息
    void handleOrderData(OrderContext orderContext, HandlerChain chain);
}
  • Handler实现类:子类结构相同,执行各自的具体逻辑
@Component
public class StrategyAHandler implements Handler {
    // 处理用户数据消息
    public void handleUserData(UserContext userContext, HandlerChain chain) {
        // ...
        // 核心方法,触发流转到下一个handler
        chain.doHandle(userContext);
    }
    // 处理订单数据消息
    public void handleOrderData(OrderContext orderContext, HandlerChain chain) {
        ...
        // 核心方法,触发流转到下一个handler
        chain.doHandle(orderContext);
    }
}

@Component
public class StrategyBHandler implements Handler {
 // ...
}

@Component
public class UploadHandler implements Handler {
 // ...
}

3.Context类

  • Context抽象类:定义公共参数
    • param:处理到最后要发http请求,因此构建一个公共的JSONObject类型参数
    • position:标记即将执行的handler所在位置
@Data
public abstract class AbstractContext {
    private JSONObject param = new JSONObject();
    private int position = 0;
}
  • Context实现类:定义每一种消息独有的参数
@Data
public class UserContext extends AbstractContext {
    private UserInfo userInfo;
    
    public UserContext(UserInfo userInfo) {
        this.userInfo = userInfo;
    }
}
@Data
public class OrderContext extends AbstractContext {
    private OrderInfo orderInfo;
    
    public OrderContext(OrderInfo orderInfo) {
        this.orderInfo = orderInfo;
    }
}

4.Handler组装类

  • 作用:接收Kafka消息,把各种策略按任意顺序组装
@Component
public class DemoService {
    @Autowired
    private StrategyAHandler strategyAHandler;
    @Autowired
    private StrategyBHandler strategyBHandler;
    @Autowired
    private UploadHandler uploadHandler;
    
    // 处理Kafka发来的用户信息
    public void handleUserData(UserInfo userInfo) {
        HandlerChain chain = new HandlerChain();
        chain.addHandler(strategyAHandler);
        chain.addHandler(strategyBHandler);
        chain.addHandler(uploadHandler);
        UserContext userContext = new UserContext(userInfo);
        chain.doHandle(userContext);
    }
    
    // 处理Kafka发来的订单信息
    public void handleOrderData(OrderInfo orderInfo) {
        HandlerChain chain = new HandlerChain();
        chain.addHandler(strategyBHandler);
        chain.addHandler(strategyAHandler);
        chain.addHandler(uploadHandler);
        OrderContext orderContext = new OrderContext(orderInfo);
        chain.doHandle(orderContext);
    }
}

四、总结

  • Handler实现类交给Spring框架来管理,Context和HandlerChain则是每次调用创建一份
  • 实现效果是可以把某个策略的代码收敛在一个Handler实现类中
  • 如果需要去掉某个策略,直接把该策略从chain中去除即可

转载链接:https://juejin.cn/post/7585005164727451686


Tags:


本篇评论 —— 揽流光,涤眉霜,清露烈酒一口话苍茫。


    声明:参照站内规则,不文明言论将会删除,谢谢合作。


      最新评论




ABOUT ME

Blogger:袅袅牧童 | Arkin

Ido:PHP攻城狮

WeChat:nnmutong

Email:nnmutong@icloud.com

标签云