设计模式之——责任链模式

客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁是具体的处理对象,让多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条调用链,并沿着这条链传递该请求,直到有一个对象处理它才终止

有两个核心行为:一是处理请求,二是将请求传递到下一节点

 

应用场景

  • Apache Tomcat 对 Encoding 编码处理的处理,SpringBoot里面的拦截器、过滤器链
  • 在请求处理者不明确的情况下向多个对象中的一个提交请求
  • 如果有多个对象可以处理同一个请求,但是具体由哪个对象处理是由运行时刻动态决定的,这种对象就可以使用职责链模式

 

角色

Handler抽象处理者:定义了一个处理请求的接口

ConcreteHandler具体处理者: 处理所负责的请求,可访问它的后续节点,如果可处理该请求就处理,否则就将该请求转发给它的后续节点

 

代码实现

需求:

风控规则,就是对于每个场景,定义一些规则,来进行相应的控制,比如银行借款、支付宝提现、大额转账等 会触发不同的策略
像互联网金融行业的话,除了公司内部政策,所处的外部环境经常发生变化,比如国家经常会出政策,这些都经常需要调整相应的风控参数和风控级别
例子:支付宝转账,根据转账额度不同,会触发的风控级别不一样,1000元以下直接转,1千到1万需要手机号验证码,1万到以上需要刷脸验证

public class Request {

    /**
     * 类别
     */
    private String requestType;
​
    /**
     * 金额
     */
    private int money;
  
    //set get方法省略
}
public enum RequestType {

    /**
     * 转账
     */
    TRANSFER,
​
    /**
     * 提现
     */
    CASH_OUT;
}

抽象接口

public abstract class RiskControlManager {

    protected  String name;
​
    /**
     * 更严格的风控策略
     */
    protected RiskControlManager superior;
​
    public RiskControlManager(String name){
        this.name = name;
    }

    /**
     * 设置更严格的风控策略
     * @param superior
     */
    public void setSuperior(RiskControlManager superior){
        this.superior = superior;
    }

    /**
     * 处理请求
     * @param request
     */
    public abstract void handlerRequest(Request request);
}

接口实现

public class FirstRiskControlManager extends RiskControlManager {
​
    public FirstRiskControlManager(String name) {
        super(name);
    }
​
    /**
     *  1000元以内可以直接处理
     * @param request
     */
    @Override
    public void handlerRequest(Request request) {
​
        if(RequestType.valueOf(request.getRequestType())!=null && request.getMoney()<=1000){
​
            System.out.println("普通操作,输入支付密码即可");
​
            System.out.println(name+":"+request.getRequestType() + ", 金额:"+request.getMoney() +" 处理完成");
​
        }else {
            //下个节点进行处理
            if(superior!=null){
                superior.handlerRequest(request);
            }
        }
    }
}
public class SecondRiskControlManager extends RiskControlManager {
​
    public SecondRiskControlManager(String name) {
        super(name);
    }
​
    /**
     * 处理 1千到1万之间
     * @param request
     */
    @Override
    public void handlerRequest(Request request) {
        if(RequestType.valueOf(request.getRequestType())!=null && request.getMoney()>1000 && request.getMoney()<10000){
            System.out.println("稍大额操作,输入支付密码+短信验证码即可");
​
            System.out.println(name+":"+request.getRequestType() + ", 金额:"+request.getMoney() +" 处理完成");
        }else {
            //下个节点进行处理
            if(superior!=null){
                superior.handlerRequest(request);
            }
        }
    }
}
public class ThirdRiskControlManager extends RiskControlManager {
​
    public ThirdRiskControlManager(String name) {
        super(name);
    }
​
    @Override
    public void handlerRequest(Request request) {
        if(RequestType.valueOf(request.getRequestType())!=null && request.getMoney()>10000){
​
            System.out.println("大额操作,输入支付密码+验证码+人脸识别 ");
​
            System.out.println(name+":"+request.getRequestType() + ", 金额:"+request.getMoney() +" 处理完成");
​
        }else {
            //下个节点进行处理
            if(superior!=null){
                superior.handlerRequest(request);
            }
        }
    }
}

测试

public static void main(String[] args) {
​
    RiskControlManager firstControlManager = new FirstRiskControlManager("初级风控");
​
    RiskControlManager secondControlManager = new SecondRiskControlManager("中级风控");
​
    RiskControlManager thirdControlManager = new ThirdRiskControlManager("高级风控");
​
    //形成调用链
    firstControlManager.setSuperior(secondControlManager);
    secondControlManager.setSuperior(thirdControlManager);
​
    //使用 
    Request request1 = new Request();
    request1.setRequestType(RequestType.CASH_OUT.name());
    request1.setMoney(20000);
    firstControlManager.handlerRequest(request1);
}

优点

  1. 客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者 降低了耦合度
  2. 通过改变链内的调动它们的次序,允许动态地新增或者删除处理类,比较很方便维护
  3. 增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则
  4. 每个类只需要处理自己该处理的工作,明确各类的责任范围,满足单一职责原则

 

缺点

  1. 处理都分散到了单独的职责对象中,每个对象功能单一,要把整个流程处理完,需要很多的职责对象,会产生大量的细粒度职责对象
  2. 不能保证请求一定被接收;
  3. 如果链路比较长,系统性能将受到一定影响,而且在进行代码调试时不太方便
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值