DesignPattern - 责任链模式【行为型】
# 一、责任链模式介绍
责任链模式(Chain of Responsibility Pattern)客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁具体的处理对象,让多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条调用链,并沿着这条链传递该请求,直到有一个对象处理它才终止。
2 个核心行为:一是处理请求,二是将请求传递到下一节点
核心组成
- Handler 抽象处理者:定义一个处理请求的接口
- ConcreteHandler 具体处理者:处理所负责的请求,可访问它的后续节点,如果可处理该请求就处理,否则就将该请求转发给它的后续节点
应用场景
- SprintBoot 里的拦截器、过滤器链
- Okhttp 里的请求拦截器
- 在请求处理者不明确的情况下向多个对象中的一个提交请求
- 如果有多个对象可以处理同一个请求,但是具体由哪个对象处理是由运行时动态决定的,这种对象就可以使用职责链模式
优点
- 客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递,所以责任链将请求的发送者和请求的处理者降低了耦合度
- 通过改变链内的调动它们的次序,允许动态地新增或者删除处理类,比较方便维护
- 增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则
- 每个类只需要处理自己该处理的工作,明确各类的责任范围,满足单一职责原则
缺点
- 处理都分散到了单独的职责对象中,每个对象功能单一,要把整个流程处理完,需要很多的职责对象,会产生大量的细粒度职责对象
- 不能保证请求一定被接收,如果链路比较长,系统性能将受到一定影响,而且在进行代码调度时不太方便
# 二、责任链模式代码实现
以支付宝转账风控为例,根据转账额度不同,会触发的风控级别不一样,1 千以下直接转,1 千到 1 万需要手机号验证码,1 万以上需要刷脸验证。下面使用责任链模式来实现这 3 种风控处理:
创建账号请求类:
/**
* 转账请求
*
* @author GitLqr
*/
public class TransferRequest {
// 金额
private int money;
public TransferRequest(int money) {
super();
this.money = money;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
创建 抽象处理者:
说明:定义一个所有处理者必须实现的处理方法,还需要持有下个处理者的引用
/**
* 抽象处理者:风控抽象类
*
* @author GitLqr
*/
public abstract class AbstractRiskControlHandler {
// 当前风控处理器名称
protected String name;
// 下一级风控处理器
protected AbstractRiskControlHandler superior;
public AbstractRiskControlHandler(String name) {
super();
this.name = name;
}
/**
* 处理转账请求
*/
public abstract void handleRequest(TransferRequest transferRequest);
public AbstractRiskControlHandler getSuperior() {
return superior;
}
public void setSuperior(AbstractRiskControlHandler superior) {
this.superior = superior;
}
}
创建 具体处理者:
/**
* 具体处理者:初级风控处理器
*
* @author GitLqr
*/
public class FirstRiskControlHandler extends AbstractRiskControlHandler {
public FirstRiskControlHandler(String name) {
super(name);
}
@Override
public void handleRequest(TransferRequest transferRequest) {
if (transferRequest.getMoney() <= 1000) {
System.out.println("普通操作,输入支付密码即可");
System.out.println(name + ",转账金额:" + transferRequest.getMoney() + " 处理完成");
} else {
// 下个节点进行处理
if (superior != null) {
superior.handleRequest(transferRequest);
}
}
}
}
/**
* 具体处理者:中级风控处理器
*
* @author GitLqr
*/
public class SecondRiskControlHandler extends AbstractRiskControlHandler {
public SecondRiskControlHandler(String name) {
super(name);
}
@Override
public void handleRequest(TransferRequest transferRequest) {
if (transferRequest.getMoney() > 1000 && transferRequest.getMoney() <= 10000) {
System.out.println("稍大额操作,输入支付密码+短信验证码即可");
System.out.println(name + ",转账金额:" + transferRequest.getMoney() + " 处理完成");
} else {
// 下个节点进行处理
if (superior != null) {
superior.handleRequest(transferRequest);
}
}
}
}
/**
* 具体处理者:高级风控处理器
*
* @author GitLqr
*/
public class ThirdRiskControlHandler extends AbstractRiskControlHandler {
public ThirdRiskControlHandler(String name) {
super(name);
}
@Override
public void handleRequest(TransferRequest transferRequest) {
if (transferRequest.getMoney() > 10000) {
System.out.println("大额操作,输入支付密码+短信验证码+人脸识别");
System.out.println(name + ",转账金额:" + transferRequest.getMoney() + " 处理完成");
} else {
// 下个节点进行处理
if (superior != null) {
superior.handleRequest(transferRequest);
}
}
}
}
使用:
public static void main(String[] args) {
AbstractRiskControlHandler firstControlHandler = new FirstRiskControlHandler("初级风控");
AbstractRiskControlHandler secondControlHandler = new SecondRiskControlHandler("中级风控");
AbstractRiskControlHandler thirdControlHandler = new ThirdRiskControlHandler("高级风控");
// 形成调用链
firstControlHandler.setSuperior(secondControlHandler);
secondControlHandler.setSuperior(thirdControlHandler);
TransferRequest request = new TransferRequest(1000); // 1600, 20000
firstControlHandler.handleRequest(request);
}
- 01
- Flutter - 危!3.24版本苹果审核被拒!11-13
- 02
- Flutter - 轻松搞定炫酷视差(Parallax)效果09-21
- 03
- Flutter - 轻松实现PageView卡片偏移效果09-08