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

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

前言

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

定义

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

如何理解

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

比如说给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;
    }
}
AI 代码解读

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;
        }
    }
}
AI 代码解读

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;
        }
    }
}
AI 代码解读

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;
        }
    }
}
AI 代码解读

Order

public interface Order {

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

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

}
AI 代码解读

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;
    }
}
AI 代码解读

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;
    }
}
AI 代码解读

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);
    }
}
AI 代码解读

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);
    }
}
AI 代码解读

测试结果

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

ConsumeOrder{
   
   payType='bai_tiao', amount=301} canPay: false
AI 代码解读

优点

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

缺点

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

应用场景

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

责任链模式的两种情况

纯的职责链模式

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

不纯的职责链模式

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

注意的点

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

参考文章

结尾

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

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

相关文章
TON链上实现DAppSwap系统开发技术规则
在TON链上开发DAppSwap去中心化数字资产交换平台,需经历前期准备、系统架构设计、智能合约开发、前后端开发、系统集成测试及部署运维等阶段,确保系统的安全性、稳定性和合规性。
联盟链的优势 | 联盟链开发建设思路
联盟链采用身份认证和权限控制,可以精确控制节点的访问权限。同时,所有的节点均参与数据验证和共识机制,确保数据的安全性和不可篡改性。此外,在联盟链中,每个节点都有自己的存储设备,可以避免数据遗失和中心化失效的风险。
CMMI5大成熟度等级和4大过程域
CMMI5大成熟度等级和4大过程域
394 0
深入分析以太链/波场链/火币链/币安链LP代币合约流动性质押挖矿分红机制系统开发详细逻辑及源码
 Fabric's smart contract is called chain code, which is divided into system chain code and user chain code. System chain code is used to realize system level functions, and user chain code is used to realize user application functions. The chain code is compiled into an independent application that
深度分析:DeFi质押合约项目DAPP系统开发逻辑方案丨关于DeFi是否持有永动机效益
深度分析:DeFi质押合约项目DAPP系统开发逻辑方案丨关于DeFi是否持有永动机效益
206 0
【活动】数据质量与数据治理的发展趋势、政策标准、技术方法和实践应用全在这了!
9月10日,第四届数据质量管理国际峰会将在北京举行,届时阿里数据的高级数据技术专家王伟将会在现场分享来自阿里巴巴的数据质量与管理经验。
1340 0
【活动】数据质量与数据治理的发展趋势、政策标准、技术方法和实践应用全在这了!