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

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

前言

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

定义

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

如何理解

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

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

参考文章

结尾

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

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

相关文章
|
10月前
|
安全 项目管理
一文搞懂需求流程规范的制定方法和落地技巧
随着业务和产品的发展、团队的不断扩大,很多团队都不可避免的会遇到需求流程混乱的问题。虽然有的团队也编写了一些“需求流程规范”的文档,但最终却流于纸面,难以在团队真正落地。如何科学制定并有效落实需求管理规范呢?对此,云效产品经理陈逊进行了非常详细的直播分享,本文是他经验的文字总结。
102803 19
|
3月前
|
存储 安全 前端开发
TON链上实现DAppSwap系统开发技术规则
在TON链上开发DAppSwap去中心化数字资产交换平台,需经历前期准备、系统架构设计、智能合约开发、前后端开发、系统集成测试及部署运维等阶段,确保系统的安全性、稳定性和合规性。
|
10月前
|
人工智能 自然语言处理
内容生成与交付中,AIGC平台的责任边界
【2月更文挑战第13天】内容生成与交付中,AIGC平台的责任边界
107 3
内容生成与交付中,AIGC平台的责任边界
|
10月前
|
运维 监控 安全
如何制定科学有效的需求流程规范话题浅谈
【1月更文挑战第1天】如何制定科学有效的需求流程规范话题浅谈
|
存储 算法 安全
联盟链的优势 | 联盟链开发建设思路
联盟链采用身份认证和权限控制,可以精确控制节点的访问权限。同时,所有的节点均参与数据验证和共识机制,确保数据的安全性和不可篡改性。此外,在联盟链中,每个节点都有自己的存储设备,可以避免数据遗失和中心化失效的风险。
|
项目管理
CMMI五大成熟度定义及过程管理类详解
CMMI五大成熟度定义及过程管理类详解
307 0
|
SQL 设计模式 架构师
责任链、领域模型和事务的恩怨情仇
责任链、领域模型和事务的恩怨情仇
339 1
责任链、领域模型和事务的恩怨情仇
|
设计模式 分布式计算 大数据
大数据开发基础的设计模式的责任链
当涉及大数据的开发时,设计模式是至关重要的。其中一种常见的设计模式是责任链模式,它可以有效地处理多个对象之间的请求。
107 0
|
机器学习/深度学习 传感器 人工智能
谈谈制定数据治理战略路线图的方法
对于商业世界最具前瞻性思维能力的发展来说,如数据分析、机器学习和人工智能,高质量的数据是一个关键的成功因素。因此,当涉及到数字化转型时,数据发挥着至关重要的作用。
谈谈制定数据治理战略路线图的方法