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

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

前言

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

定义

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

如何理解

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

比如说给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方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。

参考文章

结尾

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

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

相关文章
|
27天前
|
监控 数据可视化 项目管理
关键链项目管理是什么?它如何优化传统项目管理?
关键链项目管理(CCPM)由艾利·高德拉特提出,通过优化资源分配和减少多任务并行的浪费,显著提高项目执行效率与成功率。本文介绍CCPM的核心理念、与传统项目管理的区别及优势,并推荐几款支持CCPM的项目管理软件,如ProChain、板栗看板等,帮助企业更好地实施这一高效管理方法。
63 0
|
1月前
|
数据采集 监控 数据可视化
数据治理成功的九大细节,你都忽略了哪几个?
数字化时代,数据作为新的生产要素受到了各界前所未有的重视。
|
1月前
|
数据采集 存储 数据安全/隐私保护
CDGA|数据治理:自上而下与自下而上的双重策略
数据治理是一个复杂而长期的过程,需要企业从多个方面入手进行综合治理。自上而下和自下而上的双重策略可以相互补充、相互促进,共同推动企业数据治理工作的深入开展。在实践中,企业需要根据自身实际情况选择合适的策略和方法,确保数据治理工作的有效性和可持续性。
|
6月前
|
存储 安全 区块链
|
供应链 安全 网络安全
区块链联盟链系统开发 | 联盟链开发
区块链技术因其在金融、医疗保健和供应链管理等多个行业中的潜力而受到广泛关注。区块链系统提供了许多优点,包括透明度、安全性和不可变性。然而,传统的公共区块链系统存在一些限制,例如有限的可扩展性、缺乏隐私和高交易费用。
|
存储 算法 安全
联盟链的优势 | 联盟链开发建设思路
联盟链采用身份认证和权限控制,可以精确控制节点的访问权限。同时,所有的节点均参与数据验证和共识机制,确保数据的安全性和不可篡改性。此外,在联盟链中,每个节点都有自己的存储设备,可以避免数据遗失和中心化失效的风险。
|
SQL 设计模式 架构师
责任链、领域模型和事务的恩怨情仇
责任链、领域模型和事务的恩怨情仇
309 1
责任链、领域模型和事务的恩怨情仇
|
区块链 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