责任链模式

责任链模式(Chain of Responsibility Pattern)

定义

将请求的发送和接收解耦,让多个对象都有机会依次处理这个请求,形成一个链条。

责任链模式是将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。
当一个请求从链式的首端发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止。

属于行为型模式。

适用场景:

1.多个对象可以处理同一个请求,具体由哪个对象处理则在运行时动态决定;
2.在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
3.可动态指定一组对象处理请求。

标准示例

在这里插入图片描述
Handler 是一个抽象的处理器,下一个节点在handler中维护;
ConcreteHandlerA、ConcreteHandlerB 是两个具体的处理者。它们只处理自己职责范围内的事情,与自己无关的,抛给下一个节点来处理;
每个具体的处理者,在链条中,依次传递下去,直到找到负责该职责的处理者。
具体代码如下:
Handler

public abstract class Handler {
    protected Handler nextHandler;

    public void setNextHandler(Handler nextHandler){
        this.nextHandler = nextHandler;
    }

    public abstract void handlerRequest(String request);
}

ConcreteHandlerA

public class ConcreteHandlerA extends Handler{
    public void handlerRequest(String request) {
        if("A".equals(request)){
            System.out.println(this.getClass().getSimpleName()+" 收到请求参数:"+request);
            return ;
        }
        if(this.nextHandler!=null){
            this.nextHandler.handlerRequest(request);
        }
    }
}

ConcreteHandlerB

public class ConcreteHandlerB extends Handler{
    public void handlerRequest(String request) {
        if("B".equals(request)){
            System.out.println(this.getClass().getSimpleName()+" 收到请求参数:"+request);
            return ;
        }
        if(this.nextHandler!=null){
            this.nextHandler.handlerRequest(request);
        }
    }
}

Client

public class Client {
    public static void main(String[] args) {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        handlerA.setNextHandler(handlerB);
        handlerA.handlerRequest("B");
    }
}

client 执行结果:

ConcreteHandlerB 收到请求参数:B

再举个实际场景的例子。
我们在登录系统的时候,会有多种途径,比如账号密码,比如手机号验证码,比如微信三方授权登录。
我们就用责任链模式来实现这个业务逻辑。
我们使用BaseLoginHandler作为抽象的处理器。
AccountLoginHandler、PhoneLoginHandler、WxLoginHandler 作为具体的处理者。
代码如下:
BaseLoginHandler

@Data
public abstract class BaseLoginHandler {
    protected BaseLoginHandler nextHandler;

    public abstract void requestHandler(LoginRequestDTO request);
}

AccountLoginHandler

public class AccountLoginHandler extends BaseLoginHandler {
    public void requestHandler(LoginRequestDTO request) {
        if(!StringUtils.isAnyBlank(request.getAccount(),request.getPassword())){
            System.out.println("进入账号密码登录逻辑");
            return;
        }
        if(this.nextHandler!=null){
            this.nextHandler.requestHandler(request);
        }
    }
}

PhoneLoginHandler

public class PhoneLoginHandler extends BaseLoginHandler{
    public void requestHandler(LoginRequestDTO request) {
        if(!StringUtils.isAnyBlank(request.getPhoneNo(),request.getVerifyCode())){
            System.out.println("进入手机号验证码登录逻辑");
            return ;
        }
        if(this.nextHandler!=null){
            this.nextHandler.requestHandler(request);
        }
    }
}

WxLoginHandler

public class WxLoginHandler extends BaseLoginHandler{
    public void requestHandler(LoginRequestDTO request) {
        if(StringUtils.isNotBlank(request.getWxOpenId())){
            System.out.println("进入微信授权登录逻辑");
            return ;
        }
        if(this.nextHandler!=null){
            this.nextHandler.requestHandler(request);
        }
    }
}

LoginRequestDTO 请求参数

@Data
public class LoginRequestDTO {
    private String account;
    private String password;
    private String phoneNo;
    private String verifyCode;
    private String wxOpenId;
}

ClientTest

public class ClientTest {
    public static void main(String[] args) {
        //请求参数中只含有wxOpenid
        LoginRequestDTO requestDTO = new LoginRequestDTO();
        requestDTO.setWxOpenId("afjqweriqwjn1231324nzkfjasldfj");

        AccountLoginHandler accountHandler = new AccountLoginHandler();
        PhoneLoginHandler phoneHandler = new PhoneLoginHandler();
        WxLoginHandler wxHandler = new WxLoginHandler();
        //设置责任链顺序:account -> phone -> wx
        accountHandler.setNextHandler(phoneHandler);
        phoneHandler.setNextHandler(wxHandler);
        //执行责任链
        accountHandler.requestHandler(requestDTO);

    }
}

执行结果:

进入微信授权登录逻辑

小提示: 代码中用到的 StringUtils 是 Apache common 工具包中的,可在pom.xml中引入:

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.7</version>
    </dependency>

以上就是责任链模式全部内容,感谢阅读。

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值