java 设计模式从风控链理解责任链模式

 更新时间:2023年05月18日 11:18:04   作者:不一样的科技宅  
这篇文章主要为大家介绍了java 设计模式从风控链理解责任链模式示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

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

定义

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

如何理解

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

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

参考文章

以上就是java 设计模式从风控链理解责任链模式的详细内容,更多关于java责任链模式的资料请关注脚本之家其它相关文章!

相关文章

  • Spring核心容器IOC原理实例解析

    Spring核心容器IOC原理实例解析

    这篇文章主要介绍了Spring核心容器IOC原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java使用dom4j解析xml、读取xml文件图文教程

    Java使用dom4j解析xml、读取xml文件图文教程

    这篇文章主要给大家介绍了关于Java使用dom4j解析xml、读取xml文件的相关资料,包括创建SAXReader对象、读取并解析XML文件、获取Document对象、获取根元素和子元素、获取属性和内容等操作,还提供了配置Dom4j jar包的步骤,需要的朋友可以参考下
    2025-02-02
  • SpringMVC框架和SpringBoot项目中控制器的响应结果深入分析

    SpringMVC框架和SpringBoot项目中控制器的响应结果深入分析

    这篇文章主要介绍了SpringMVC框架和SpringBoot项目中控制器的响应结果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • Spring Boot通过Junit实现单元测试过程解析

    Spring Boot通过Junit实现单元测试过程解析

    这篇文章主要介绍了Spring Boot通过Junit实现单元测试过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java中线程间通信流程详解

    Java中线程间通信流程详解

    这篇文章主要介绍了Java中线程间通信流程,Java线程间通信主要通过​​共享内存或​​消息传递​​实现同步与数据交换,并发面试题中常会碰到这个问题,需要的朋友可以参考下
    2025-05-05
  • Java @Scheduled定时任务不执行解决办法

    Java @Scheduled定时任务不执行解决办法

    这篇文章主要给大家介绍了关于Java @Scheduled定时任务不执行解决的相关资料,当@Scheduled定时任务不执行时可以根据以下步骤进行排查和解决,需要的朋友可以参考下
    2023-10-10
  • Java中ASCII到十六进制的转换指南

    Java中ASCII到十六进制的转换指南

    在软件开发、网络通信与底层系统交互中,ASCII 字符与十六进制表示之间的转换是一项基础且高频的操作,本文将从计算机编码的底层逻辑出发,结合 Java 平台的特性,系统探讨 ASCII 转十六进制的核心机制、应用场景、设计考量与最佳实践,需要的朋友可以参考下
    2026-05-05
  • java遍历途中修改数据及删除数据的方法总结

    java遍历途中修改数据及删除数据的方法总结

    在使用java的集合类遍历数据的时候,在某些情况下可能需要对某些数据进行删除,下面这篇文章主要给大家介绍了关于java遍历途中修改数据及删除数据的方法总结,需要的朋友可以参考下
    2023-10-10
  • spring boot中的properties参数配置详解

    spring boot中的properties参数配置详解

    这篇文章主要介绍了spring boot中的properties参数配置,需要的朋友可以参考下
    2017-09-09
  • java.time包时间类的具体使用

    java.time包时间类的具体使用

    本文主要介绍了java.time包时间类的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08

最新评论