责任链是一种行为型模式。顾名思义,由多个有不同处理能力节点组成的一条执行链。当一个事件进来时,会判断当前节点是否有处理的能力,反之转入下一个节点进行处理。可以从支付的风控链这个场景,深入的理解责任链模式。
责任链模式:包含了一些命令和一系列的处理对象。每一个处理对象决定了它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。
信用卡套现,花呗套现,白条套现,类似的名词对于我们来讲应该不陌生吧。在支付系统中会有一套风控系统,来避免发生类似的事情出现。而风控系统就是责任链模式的一种应用。
比如说给xxx商户配置的风控规则是:
TOP | 信用卡 | 花呗 | 白条 |
---|---|---|---|
木屋烧烤 | 500/日 | 300/日 | 300/日 |
当用户向商家付款时,会根据不同的支付方式,来判断是否触发风控条件。如果达到触发条件则不允许使用该方式支付。来避免发生信用卡套现类似的事情。
我们写个简单的风控程序来理解一下:
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;
}
}
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;
}
}
}
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;
}
}
}
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;
}
}
}
public interface Order {
/**
* 获取支付方式
* @return 支付方式
*/
String getPayType();
/**
* 获取订单金额
* @return 订单金额
*/
BigDecimal getAmount();
}
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;
}
}
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;
}
}
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);
}
}
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方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。
如果觉得对你有帮助,可以多多评论,多多点赞哦,也可以到我的主页看看,说不定有你喜欢的文章,也可以随手点个关注哦,谢谢。
我是不一样的科技宅,每天进步一点点,体验不一样的生活。我们下期见!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。