责任链细解:从风控链视角,探索责任链的设计与实践!

简介: 责任链是一种行为型模式。顾名思义,由多个有不同处理能力节点组成的一条执行链。当一个事件进来时,会判断当前节点是否有处理的能力,反之转入下一个节点进行处理。可以从支付的风控链这个场景,深入的理解责任链模式。

前言

  责任链是一种行为型模式。顾名思义,由多个有不同处理能力节点组成的一条执行链。当一个事件进来时,会判断当前节点是否有处理的能力,反之转入下一个节点进行处理。可以从支付的风控链这个场景,深入的理解责任链模式。

定义

  责任链模式:包含了一些命令和一系列的处理对象。每一个处理对象决定了它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。

如何理解

  信用卡套现,花呗套现,白条套现,类似的名词对于我们来讲应该不陌生吧。在支付系统中会有一套风控系统,来避免发生类似的事情出现。而风控系统就是责任链模式的一种应用。

比如说给xxx商户配置的风控规则是:

TOP 信用卡 花呗 白条
木屋烧烤 500/日 300/日 300/日

  当用户向商家付款时,会根据不同的支付方式,来判断是否触发风控条件。如果达到触发条件则不允许使用该方式支付。来避免发生信用卡套现类似的事情。

我们写个简单的风控程序来理解一下:

UML

代码示例

RiskHandler

public abstract class RiskHandler {
   
   

    /**
     * 支付方式
     */
    private String payType;

    private RiskHandler nextHandler;


    public RiskHandler(String payType) {
   
   
        this.payType = payType;
    }

    /**
     * 是否能支付
     * @param order 订单
     */
    protected abstract boolean canPay(Order order);


    /**
     * 处理器
     * @param order 订单
     * @return 返回true 或者 false
     */
    public final boolean handler(Order order){
   
   
        if(order.getPayType().equals(this.payType)){
   
   
            return this.canPay(order);
        }else {
   
   
            if (this.nextHandler != null){
   
   
                return this.nextHandler.handler(order);
            }else{
   
   
                throw new IllegalArgumentException("支付方式有误");
            }
        }
    }

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

CreditHandler

public class CreditHandler extends RiskHandler {
   
   

    /**
     * 500 限额
     */
    private BigDecimal limitAmount = BigDecimal.valueOf(500);


    public CreditHandler() {
   
   
        super(PayTypeEnum.CREDIT.getPayType());
    }

    @Override
    protected boolean canPay(Order order) {
   
   
        if(order.getAmount().compareTo(limitAmount) < 0){
   
   
            limitAmount = limitAmount.subtract(order.getAmount());
            return true;
        }else {
   
   
            return false;
        }
    }
}

HuabeiHandler

public class HuabeiHandler extends RiskHandler {
   
   

    /**
     * 300 限额
     */
    private BigDecimal limitAmount = BigDecimal.valueOf(300);


    public HuabeiHandler() {
   
   
        super(PayTypeEnum.HUA_BEI.getPayType());
    }

    @Override
    protected boolean canPay(Order order) {
   
   
        if(order.getAmount().compareTo(limitAmount) < 0){
   
   
            limitAmount = limitAmount.subtract(order.getAmount());
            return true;
        }else {
   
   
            return false;
        }
    }
}

BaiTiaoHandler

public class BaiTiaoHandler extends RiskHandler {
   
   

    /**
     * 300 限额
     */
    private BigDecimal limitAmount = BigDecimal.valueOf(300);

    public BaiTiaoHandler() {
   
   
        super(PayTypeEnum.BAI_TIAO.getPayType());
    }

    @Override
    protected boolean canPay(Order order) {
   
   
        if(order.getAmount().compareTo(limitAmount) < 0){
   
   
            limitAmount = limitAmount.subtract(order.getAmount());
            return true;
        }else {
   
   
            return false;
        }
    }
}

Order

public interface Order {

    /**
     * 获取支付方式
     * @return 支付方式
     */
    String getPayType();

    /**
     * 获取订单金额
     * @return 订单金额
     */
    BigDecimal getAmount();

}

ConsumeOrder

public class ConsumeOrder implements Order {

    private String payType;

    private BigDecimal amount;

    public ConsumeOrder(String payType, BigDecimal amount) {
        this.payType = payType;
        this.amount = amount;
    }

    @Override
    public String getPayType() {
        return this.payType;
    }

    @Override
    public BigDecimal getAmount() {
        return this.amount;
    }
}

PayTypeEnum

public enum  PayTypeEnum {
   
   

    /**
     * 花呗
     */
    HUA_BEI("hua_bei"),

    /**
     * 白条
     */
    BAI_TIAO("bai_tiao"),

    /**
     * 信用卡
     */
    CREDIT("credit"),

    ;

    private String payType;


    PayTypeEnum(String payType) {
   
   
        this.payType = payType;
    }

    public String getPayType() {
   
   
        return payType;
    }
}

PayRiskControlService

public class PayRiskControlService {
   
   

    public boolean canPay(Order order){
   
   

        // 设置风控
        RiskHandler creditHandler = new CreditHandler();

        RiskHandler huabeiHandler = new HuabeiHandler();

        RiskHandler baiTiaoHandler = new BaiTiaoHandler();

        creditHandler.setNextHandler(huabeiHandler);

        huabeiHandler.setNextHandler(baiTiaoHandler);

        return creditHandler.handler(order);
    }
}

Test

public class Test {
   
   

    public static void main(String[] args) {
   
   

        // 花呗订单
        ConsumeOrder huabeiOrder = new ConsumeOrder(
                PayTypeEnum.HUA_BEI.getPayType(), BigDecimal.valueOf(200)
        );

        // 白条订单
        ConsumeOrder baitiaoOrder = new ConsumeOrder(
                PayTypeEnum.BAI_TIAO.getPayType(), BigDecimal.valueOf(301)
        );

        // 加载风控系统
        PayRiskControlService riskControlService = new PayRiskControlService();

        // 创建订单
        boolean canPayOfHuabei = riskControlService.canPay(huabeiOrder);
        boolean canPayOfBaitiao = riskControlService.canPay(baitiaoOrder);

        System.out.println("canPayOfHuabei = " + canPayOfHuabei);
        System.out.println("canPayOfBaitiao = " + canPayOfBaitiao);
    }
}

测试结果

ConsumeOrder{
   
   payType='hua_bei', amount=200} canPay: true

ConsumeOrder{
   
   payType='bai_tiao', amount=301} canPay: false

优点

  • 降低耦合度,将请求和处理分开。
  • 简化了对象,是对象不需要知道链的结构。
  • 增强给对象指派职责的灵活性,通过改变链内的成员或者调动他们的次序,运行动态的新增或者删除责任。
  • 增加新的处理类很方便。

缺点

  • 不能保证请求一定被接收
  • 系统性能将受到一定影响,而且在调试代码时不太方便,可能会造成循环调用。
  • 可能不容易观察运行时的特征,有碍于除错。

应用场景

  • 有多个对象可以处理同一个请求,具体是哪个对象处理由该请求运行时刻自动确定。
  • 在不明确接受者的情况下,向多个对象中的一个提交一个请求。
  • 可以动态指定一组对象处理请求。

责任链模式的两种情况

纯的职责链模式

  一个请求必须被某一个处理者对象所接收,且一个具体处理者对某个请求的处理只能采用以下两种行为之一:自己处理(承担责任),把责任推给下家处理。

不纯的职责链模式

  允许出现某一个具体处理者对象在承担了请求的一部分责任后又将剩余的责任传给下家的情况,且一个请求可以最终不被任何接收端对象所接收。比如说,多级审核登录安全监测

注意的点

  链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。

参考文章

结尾

  如果觉得对你有帮助,可以多多评论,多多点赞哦,也可以到我的主页看看,说不定有你喜欢的文章,也可以随手点个关注哦,谢谢。

  我是不一样的科技宅,每天进步一点点,体验不一样的生活。我们下期见!

相关文章
|
4月前
|
存储 安全 区块链
|
7月前
|
存储 算法 安全
联盟链的优势 | 联盟链开发建设思路
联盟链采用身份认证和权限控制,可以精确控制节点的访问权限。同时,所有的节点均参与数据验证和共识机制,确保数据的安全性和不可篡改性。此外,在联盟链中,每个节点都有自己的存储设备,可以避免数据遗失和中心化失效的风险。
|
区块链 vr&ar
马蹄链开发方案丨马蹄链系统开发(说明及功能)丨马蹄链系统源码部署
智能合约是区块链技术世界不可或缺的一部分。 这些合约是软件程序,当满足了规定的条件时,在两个或多个参与方之间执行特定的任务。从本质上说,它就像一个自执行的常规合约,不需要中介,因为它依赖于它的编程值。
|
前端开发
火币链/波场链/OK链/币安链盲盒游戏开发功能版,火币链/波场链/OK链/币安链盲盒游戏系统开发(成熟及方案)
The explanation of the new retail is that individuals and enterprises, relying on the Internet, upgrade and transform the production, circulation and sales process of goods by using advanced technical means such as big data, artificial intelligence and psychological knowledge, thus reshaping the bus
|
数据管理 数据安全/隐私保护
数据治理晓说:(一)谈谈数据治理和公司治理的关系
下面内容讲的是数据治理与公司治理的关系。如何确保信息满足需求并将支持和授权管理人员正确有效的执行他们自己的角色。
数据治理晓说:(一)谈谈数据治理和公司治理的关系
|
SQL 设计模式 架构师
责任链、领域模型和事务的恩怨情仇
责任链、领域模型和事务的恩怨情仇
245 1
责任链、领域模型和事务的恩怨情仇
|
弹性计算 人工智能 数据可视化
数字化转型过程中需要厘清的几个关系:技术与规则
前言 在文章的开头,笔者摘用一段报告,报告内容对数字化全面转型进行了如下描述:“对于一些高管来说,这是一场关于技术的竞争。对于其他人而言,数字化是一种与客户互动的新方式,它代表了一种全新的经营方式。虽然这些定义都不一定不正确,但是这种多样化的视角却经常让领导团队‘四分五裂’。原因正是理解的不一致和缺乏对企业未来之路的共同愿景。正因为如此,企业会经常出现不连续的举措和错失方向的努力,继而表现出迟缓或从一开始就迷失方向。”
261 0
数字化转型过程中需要厘清的几个关系:技术与规则