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责任链模式的资料请关注脚本之家其它相关文章!

相关文章

  • Java Tree结构数据中查找匹配节点方式

    Java Tree结构数据中查找匹配节点方式

    这篇文章主要介绍了Java Tree结构数据中查找匹配节点方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Spring MVC中处理ajax请求的跨域问题与注意事项详解

    Spring MVC中处理ajax请求的跨域问题与注意事项详解

    跨域问题是我们大家在开发中会经常遇到的一个问题,所以下面这篇文章主要给大家介绍了关于Spring MVC中处理ajax请求的跨域问题与注意事项的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-11-11
  • SpringBoot2.0整合Shiro框架实现用户权限管理的示例

    SpringBoot2.0整合Shiro框架实现用户权限管理的示例

    这篇文章主要介绍了SpringBoot2.0整合Shiro框架实现用户权限管理的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Spring Boot实现图片上传/加水印一把梭操作实例代码

    Spring Boot实现图片上传/加水印一把梭操作实例代码

    这篇文章主要给大家介绍了关于Spring Boot实现图片上传/加水印一把梭操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • 关于Java中HashCode方法的深入理解

    关于Java中HashCode方法的深入理解

    这篇文章主要给大家介绍了关于Java中HashCode方法的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • 基于Mybatis映射的一点心得(分享)

    基于Mybatis映射的一点心得(分享)

    下面小编就为大家带来一篇基于Mybatis映射的一点心得(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Redis中4种延时队列实现方式小结

    Redis中4种延时队列实现方式小结

    Redis作为高性能的内存数据库,具备原子操作、数据结构丰富和简单易用的特性,本文将介绍基于Redis实现分布式延时队列的四种方式,大家可以根据需要进行选择
    2025-04-04
  • Mybatis拦截器的实现介绍

    Mybatis拦截器的实现介绍

    MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能。MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。下面通过本文给大家介绍Mybatis拦截器知识,感兴趣的朋友一起看看吧
    2016-10-10
  • MyBatis-Plus 分页查询的实现示例

    MyBatis-Plus 分页查询的实现示例

    本文主要介绍了MyBatis-Plus 分页查询的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java 配置log4j日志文件路径 (附-获取当前类路径的多种操作)

    Java 配置log4j日志文件路径 (附-获取当前类路径的多种操作)

    这篇文章主要介绍了Java 配置log4j日志文件路径 (附-获取当前类路径的多种操作),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10

最新评论