核心思想
- 客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁是具体的处理对象
- 让多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条调用链,并沿着这条链传递该请求,直到有一个对象处理它才终止
- 两个核心行为:一是处理请求,二是将请求传递到下一节点
场景使用
- 在请求处理者不明确的情况下向多个对象中的一个提交请求
- 如果有多个对象可以处理同一个请求,但是具体由哪个对象处理是由运行时刻动态决定的,这种对象就可以使用职责链模式
- SpringBoot里面的拦截器、过滤器链
优缺点
优点
- 客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递
- 通过改变链内的调动它们的次序,允许动态地新增或者删除处理类,比较很方便维护
- 增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则
- 每个类只需要处理自己该处理的工作,明确各类的责任范围,满足单一职责原则
缺点
- 处理都分散到了单独的职责对象中,每个对象功能单一,要把整个流程处理完
- 不能保证请求一定被接收
- 如果链路比较长,系统性能将受到一定影响,而且在进行代码调试时不太方便
代码示例
业务示意图
配置 Request 类
public class Request {
/**
* 类别
*/
private String requestType;
/**
* 金额
*/
private int money;
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
请求类型枚举 RequestType
public enum RequestType {
/**
* 转账
*/
TRANSFER,
/**
* 提现
*/
CASH_OUT;
}
风控抽象类 RiskControlManager
public abstract class RiskControlManager {
protected String name;
/**
* 更严格的风控策略
*/
protected RiskControlManager superior;
public RiskControlManager(String name){
this.name = name;
}
/**
* 设置更严格的风控策略
* @param superior
*/
public void setSuperior(RiskControlManager superior){
this.superior = superior;
}
/**
* 处理请求
* @param request
*/
public abstract void handlerRequest(Request request);
}
初级风控 FirstRiskControlManager
public class FirstRiskControlManager extends RiskControlManager {
public FirstRiskControlManager(String name) {
super(name);
}
/**
* 1000元以内可以直接处理
* @param request
*/
@Override
public void handlerRequest(Request request) {
if(RequestType.valueOf(request.getRequestType())!=null && request.getMoney()<=1000){
System.out.println("普通操作,输入支付密码即可");
System.out.println(name+":"+request.getRequestType() + ", 金额:"+request.getMoney() +" 处理完成");
}else {
//下个节点进行处理
if(superior!=null){
superior.handlerRequest(request);
}
}
}
}
中级风控
public class SecondRiskControlManager extends RiskControlManager {
public SecondRiskControlManager(String name) {
super(name);
}
/**
* 处理 1千到1万之间
* @param request
*/
@Override
public void handlerRequest(Request request) {
if(RequestType.valueOf(request.getRequestType())!=null && request.getMoney()>1000 && request.getMoney()<10000){
System.out.println("稍大额操作,输入支付密码+短信验证码即可");
System.out.println(name+":"+request.getRequestType() + ", 金额:"+request.getMoney() +" 处理完成");
}else {
//下个节点进行处理
if(superior!=null){
superior.handlerRequest(request);
}
}
}
}
高级风控 ThirdRiskControlManager
public class ThirdRiskControlManager extends RiskControlManager {
public ThirdRiskControlManager(String name) {
super(name);
}
@Override
public void handlerRequest(Request request) {
if(RequestType.valueOf(request.getRequestType())!=null && request.getMoney()>10000){
System.out.println("大额操作,输入支付密码+验证码+人脸识别 ");
System.out.println(name+":"+request.getRequestType() + ", 金额:"+request.getMoney() +" 处理完成");
}else {
//下个节点进行处理
if(superior!=null){
superior.handlerRequest(request);
}
}
}
}
测试
public static void main(String[] args) {
RiskControlManager firstControlManager = new FirstRiskControlManager("初级风控");
RiskControlManager secondControlManager = new SecondRiskControlManager("中级风控");
RiskControlManager thirdControlManager = new ThirdRiskControlManager("高级风控");
//形成调用链
firstControlManager.setSuperior(secondControlManager);
secondControlManager.setSuperior(thirdControlManager);
//使用
Request request1 = new Request();
request1.setRequestType(RequestType.CASH_OUT.name());
request1.setMoney(21000);
firstControlManager.handlerRequest(request1);
}