关于责任链模式在实际生产中的应用

本文介绍了如何利用责任链模式改进火车票抢票软件的登录逻辑。在12306风控加剧导致频繁更换登录方式的情况下,原有的代码逻辑复杂,分析问题困难。通过引入责任链模式,将登录态登录、扫码登录、用户名密码登录等处理方式解耦,实现了登录方式的依次尝试,直到成功。每个登录处理器作为链上的节点,依次处理登录请求,提高了代码的可读性和维护性。同时,登录处理顺序可根据需求动态调整,结果处理采用了策略模式。
摘要由CSDN通过智能技术生成

关于责任链模式在实际生产中的应用

一.背景

我司是做火车票抢票软件的,做抢票软件就少不了需要登录12306,近期12306风控比较严重,导致登录的时候老是需要换登录方式,常见的登录有登录态登录,扫码登录,用户名密码登录,只要有一个登录失败就会进行下一个登录方式,直到登录成功为止,而原先的代码所有的业务逻辑都耦合在一起,查看问题时需要查看全局代码,逻辑又比较复杂,分析问题的时候需要很长时间,现需要对该逻辑进行优化。

二.分析

2.1 分析

经过对代码的分析,决定采用责任链的模式对逻辑进行优化。

2.2什么是责任链模式

责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止,看责任链的定义刚好符合我的需要。

三.代码编写

3.1编写登录处理接口

public interface LoginHandler<T> {
    void doLogin(LoginContext<T> loginContext, LoginHandlerChain chain);
}

3.2创建登录执行链类

public class LoginHandlerChain implements LoginHandler {

    private List<LoginHandler> handlerList;

    private int position;

    public void addLoginFilter(LoginHandler loginHandler) {
        if (null == handlerList) {
            handlerList = new ArrayList<>();
        }
        handlerList.add(loginHandler);
    }


    @Override
    public void doLogin(LoginContext loginContext, LoginHandlerChain chain) {
        //省略业务逻辑
        if (loginContext.getFinished()||position >= handlerList.size()) {
            return;
        }
        handlerList.get(position++).doLogin(loginContext, chain);
    }
}

3.3创建存储登录上下文的类

public class LoginContext {
   
    private boolean finished;

    public boolean getFinished() {
        return finished;
    }

    public void setFinished(boolean finished) {
        this.finished = finished;
    }
}

3.4创建登录态登录实现类


public class SessionLoginHandler implements LoginHandler<Browser> {

    @Override
    public void doLogin(LoginContext<Browser> ctx, LoginHandlerChain chain) {
       //根据业务逻辑处理
       if(登录态登录成功){
       ctx.setFinished(true);
       return;
       }
       chain.doLogin(context, chain);
    }
        }

3.5创建扫码登录实现类

public class ScanCodeLoginHandler implements LoginHandler<Broswer> {

    @Override
    public void doLogin(LoginContext<Broswer> ctx, LoginHandlerChain chain) {
       //根据业务逻辑处理
       if(扫码登录成功){
       ctx.setFinished(true);
        return;
       }
       chain.doLogin(context, chain);
    }
        }

3.6创建用户名密码实现类

public class UserNameLoginHandler implements LoginHandler<Broswer> {

    @Override
    public void doLogin(LoginContext<Broswer> ctx, LoginHandlerChain chain) {
       //根据业务逻辑处理
       if(用户名密码登录成功){
       ctx.setFinished(true);
       return;
       }
       chain.doLogin(context, chain);
    }
        }

3.7生成执行链

@Test
    public void test2(){
        LoginHandlerChain chain = new LoginHandlerChain();
        chain.addLoginFilter(new SessionLoginHandler());
        chain.addLoginFilter(new ScanCodeLoginHandler());
        chain.addLoginFilter(new UserNameLoginHandler());
        LoginContext context = new LoginContext<>();
        chain.doLogin(context, chain);
  }

四.总结

由于保密性原则,逻辑代码没有写,只是记录碰到相应场景应该如何使用相应的设计模式解决问题,当然我们真正的代码都是交给spring管理的,生成的责任链并且是可以实时刷新的,只需要更改配置就可以更换里面处理的顺序,其中返回的结果又使用的策略模式进行处理,由于之前文章记录过这里不做记录。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值