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

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

前言

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

定义

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

如何理解

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

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

参考文章

结尾

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

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

相关文章
|
6月前
|
存储 监控 安全
OT安全的本质:实现CISA网络安全绩效目标的前瞻性指南
OT安全的本质:实现CISA网络安全绩效目标的前瞻性指南
OT安全的本质:实现CISA网络安全绩效目标的前瞻性指南
|
4月前
|
数据采集 监控 数据可视化
数据治理成功的九大细节,你都忽略了哪几个?
数字化时代,数据作为新的生产要素受到了各界前所未有的重视。
|
存储 算法 安全
联盟链的优势 | 联盟链开发建设思路
联盟链采用身份认证和权限控制,可以精确控制节点的访问权限。同时,所有的节点均参与数据验证和共识机制,确保数据的安全性和不可篡改性。此外,在联盟链中,每个节点都有自己的存储设备,可以避免数据遗失和中心化失效的风险。
|
设计模式 分布式计算 大数据
大数据开发基础的设计模式的责任链
当涉及大数据的开发时,设计模式是至关重要的。其中一种常见的设计模式是责任链模式,它可以有效地处理多个对象之间的请求。
103 0
|
资源调度 前端开发 JavaScript
马蹄链智能合约系统开发功能需求丨MetaForce佛萨奇2.0波场链
马蹄链智能合约系统开发功能需求丨MetaForce佛萨奇2.0波场链
128 0
|
机器学习/深度学习 传感器 人工智能
谈谈制定数据治理战略路线图的方法
对于商业世界最具前瞻性思维能力的发展来说,如数据分析、机器学习和人工智能,高质量的数据是一个关键的成功因素。因此,当涉及到数字化转型时,数据发挥着至关重要的作用。
谈谈制定数据治理战略路线图的方法
|
数据采集 存储 监控
谈谈如何制定数据治理策略
在这篇文章中,我们将讨论为什么数据治理很重要,以及数据治理策略应该包括什么以及如何制定数据策略。
|
存储 数据挖掘 大数据
谈一谈制定数据和分析战略的重要性
随着世界变得越来越智能,数据成为企业竞争优势的关键要素,这意味着企业的竞争能力将越来越取决于如何利用数据、应用分析和实施新技术。
|
数据采集 数据管理 大数据
【活动】数据质量与数据治理的发展趋势、政策标准、技术方法和实践应用全在这了!
9月10日,第四届数据质量管理国际峰会将在北京举行,届时阿里数据的高级数据技术专家王伟将会在现场分享来自阿里巴巴的数据质量与管理经验。
1316 0
【活动】数据质量与数据治理的发展趋势、政策标准、技术方法和实践应用全在这了!