找回密码
 立即注册
首页 业界区 业界 说说设计模式~管道模式(pipeline)

说说设计模式~管道模式(pipeline)

痨砖 前天 21:00
回到目录
说明

复合的责任链,类似于管道模式,只要符合条件,说会向下传递,不会终止
算法说明


  • 按最高优先级去使用,符合就用,不符合就走下一个策略
  • 具体链条,有点像pipeline管道模式

    • BlackHandler ip=172.17.0.11
    • RateLimitHandler header=is-black
    • WriteBlackHandler header=real-black

继承抽象类


  • AbstractHandler 抽象的责任处理者

    • 抽象方法action,需要各个子类【具体的责任处理者】自己去实现
    • final修饰的方法,封装了实现细节,子类不能重写
    • setNextHandler方法,设置下一个链条的【责任处理者】

  • HandlerFactory 责任工厂

    • 通过一个责任处理列表,返回一个责任链条
    • 责任链条可以持久化到数据库里

责任链如果没有终止条件,就类似于pipeline管道了

graph  TDRequest[post body]-->A[BlackHandler]A --> B[RateLimitHandler]B --> C[WriteBlackHandler]C --> D[EndHandler]测试代码

抽象处理者
  1. public abstract class AbstractHandler<T> {
  2.         private AbstractHandler nextHandler;
  3.         public final void setNextHandler(AbstractHandler nextHandler) {
  4.                 this.nextHandler = nextHandler;
  5.         }
  6.         protected abstract void action(T body);
  7.         // final表示不允许子类重写
  8.         public final void handleRequest(T body) {
  9.                 action(body);
  10.                 if (this.nextHandler != null)
  11.                         this.nextHandler.handleRequest(body);
  12.         }
  13. }
复制代码
具体处理者
  1. public class BlackHandler extends AbstractHandler<Request> {
  2.         private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
  3.         @Override
  4.         public void action(Request body) {
  5.                 logger.info("BlackHandler 处理");
  6.         }
  7. }
  8. public class RateLimitHandler extends AbstractHandler<Request> {
  9.         private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
  10.         @Override
  11.         protected void action(Request body) {
  12.                 logger.info("RateLimitHandler 处理");
  13.         }
  14. }
  15. public class WriteBlackHandler extends AbstractHandler<Request> {
  16.         private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
  17.         @Override
  18.         protected void action(Request body) {
  19.                 logger.info("WriteBlackHandler 处理");
  20.         }
  21. }
  22. public class EndHandler extends AbstractHandler<Request> {
  23.         private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
  24.         @Override
  25.         protected void action(Request body) {
  26.                 logger.info("EndHandler 处理");
  27.         }
  28. }
复制代码
处理者工厂和请求数据体
  1. public class HandlerFactory {
  2.         public static <T extends Request> AbstractHandler<T> createHandler(List> handlerModels) {
  3.                 AbstractHandler<T> handler = null;
  4.                 AbstractHandler<T> previousHandler = null;
  5.                 for (AbstractHandler<T> currentHandler : handlerModels.stream().collect(Collectors.toList())) {
  6.                         if (previousHandler != null) {
  7.                                 previousHandler.setNextHandler(currentHandler);
  8.                         }
  9.                         else {
  10.                                 handler = currentHandler;
  11.                         }
  12.                         previousHandler = currentHandler;
  13.                 }
  14.                 return handler;
  15.         }
  16. }
  17. @AllArgsConstructor
  18. @NoArgsConstructor
  19. @Data
  20. public class Request {
  21.         private String ip;
  22.         private String userId;
  23. }
复制代码
测试用例
  1. public static void main(String[] args) {
  2.                 List> abstractHandlers = Arrays.asList(new RateLimitHandler(), new BlackHandler(),
  3.                                 new WriteBlackHandler(),new EndHandler());
  4.                 AbstractHandler<Request> abstractHandler = HandlerFactory.createHandler(abstractHandlers);
  5.                 abstractHandler.handleRequest(new Request("1", "user1"));
  6.         }
复制代码
如果希望将你的责任链处理存储到数据库中,那个在handleFactory里,就需要接口className了,例如下面的代码:
  1. public static Handler handlerFactory() {
  2.                 List<HandlerModel> handlerModels = new ArrayList<>();
  3.                 handlerModels
  4.                                 .add(new HandlerModel("CouponHandler", "com.lind.common.pattern.chinaorder.handler.CouponHandler", 1));
  5.                 handlerModels.add(
  6.                                 new HandlerModel("DiscountHandler", "com.lind.common.pattern.chinaorder.handler.DiscountHandler", 2));
  7.                 handlerModels.add(
  8.                                 new HandlerModel("BigGiftHandler", "com.lind.common.pattern.chinaorder.handler.BigGiftHandler", 3));
  9.                 handlerModels.add(new HandlerModel("VipHandler", "com.lind.common.pattern.chinaorder.handler.VipHandler", 4));
  10.                 return createHandler(handlerModels);
  11.         }
  12.         private static Handler createHandler(List<HandlerModel> handlerModels) {
  13.                 Handler handler = null;
  14.                 Handler previousHandler = null;
  15.                 for (HandlerModel handlerModel : handlerModels.stream().sorted().collect(Collectors.toList())) {
  16.                         try {
  17.                                 Handler currentHandler = (Handler) Class.forName(handlerModel.getClassPath()).newInstance();
  18.                                 if (previousHandler != null) {
  19.                                         previousHandler.setNextHandler(currentHandler);
  20.                                 }
  21.                                 else {
  22.                                         handler = currentHandler;
  23.                                 }
  24.                                 previousHandler = currentHandler;
  25.                         }
  26.                         catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  27.                                 throw new RuntimeException(e);
  28.                         }
  29.                 }
  30.                 return handler;
  31.         }
复制代码
回到目录

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册