参考链接: Java设计模式13:责任链模式.
什么是责任链模式
责任链设计模式(Chain of Responsibility Pattern)客户端发出⼀个请求,链上的对象都有机会来处理这⼀请求,⽽客户端不需要知道谁是具体的处理对象让多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系,将这个对象连成⼀条调⽤链,并沿着这条链传递该请求,直到有⼀个对象处理它才终⽌
有两个核⼼⾏为:
- 处理请求,
- 将请求传递到下⼀节点
应⽤场景
- Apache Tomcat 对 Encoding 编码处理的处理,
- SpringBoot⾥⾯的拦截器、过滤器链
- netty 中的处理链
- 支付风控的机制
- ⽇志处理级别
- 在请求处理者不明确的情况下向多个对象中的⼀个提交 请求 如果有多个对象可以处理同⼀个请求,但是具体由哪个
- 对象处理是由运⾏时刻动态决定的,这种对象就可以使 ⽤职责链模式
优缺点
优点
- 客户只需要将请求发送到职责链上即可,⽆须关⼼请求
的处理细节和请求的传递,所以职责链将请求的发送者
和请求的处理者 降低了耦合度 - 通过改变链内的调动它们的次序,允许动态地新增或者
删除处理类,⽐较很⽅便维护 - 增强了系统的可扩展性,可以根据需要增加新的请求处
理类,满⾜开闭原则
-每个类只需要处理⾃⼰该处理的⼯作,明确各类的责任
范围,满⾜单⼀职责原则
缺点
- 处理都分散到了单独的职责对象中,每个对象功能单
⼀,要把整个流程处理完,需要很多的职责对象,会产
⽣⼤量的细粒度职责对象 - 不能保证请求⼀定被接收,可以将最终操作放在最后执行
- 如果链路⽐较⻓,系统性能将受到⼀定影响,⽽且在进
⾏代码调试时不太⽅便
支付风控需求
实现:
金额小于200直接支付
200-400 请输入支付密码
400-1000 请发生短信验证码
1000以上 扫脸支付
代码实现
import java.math.BigDecimal;
/**
* @author zhou
* 参数对象
*/
public class MyParam {
/**
* 金额
*/
private BigDecimal amount;
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
}
/**
* @author zhou
*/
public interface PrepareFilter {
Integer getShort();
void doFilter(MyParam param, MyFilterChain filterChain,Integer index);
}
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 责任链处理器
*/
@Service("MyFilterChain")
public class MyFilterChain implements PrepareFilter, ApplicationContextAware {
private static List<PrepareFilter> prepareFilterList;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, PrepareFilter> serviceMap = applicationContext.getBeansOfType(PrepareFilter.class);
prepareFilterList = new ArrayList<>(serviceMap.values());
prepareFilterList = prepareFilterList.stream()
.sorted(Comparator.comparing(PrepareFilter::getShort))
.collect(Collectors.toList());
}
@Override
public Integer getShort() {
return 0;
}
@Override
public void doFilter(MyParam param, MyFilterChain filterChain, Integer index) {
index = index + 1;
if (index < prepareFilterList.size()) {
prepareFilterList.get(index).doFilter(param, filterChain, index);
} else {
System.out.println("直接支付");
}
}
}
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@Service("Filter1")
public class Filter1 implements PrepareFilter {
/**
* 这些都可以进行数据库配置
*/
public static final BigDecimal start = new BigDecimal("200");
/**
* 这些都可以进行数据库配置
*/
public static final BigDecimal end = new BigDecimal("400");
/**
* 这些都可以进行数据库配置
*/
@Override
public Integer getShort() {
return 1;
}
@Override
public void doFilter(MyParam param, MyFilterChain filterChain, Integer index) {
System.out.println("Filter1");
if (param.getAmount().compareTo(start) > -1 && param.getAmount().compareTo(end) < 0) {
System.out.println("请输入支付密码");
return;
}
filterChain.doFilter(param, filterChain, index);
}
}
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@Service("Filter2")
public class Filter2 implements PrepareFilter {
public static final BigDecimal start = new BigDecimal("400");
public static final BigDecimal end = new BigDecimal("1000");
@Override
public Integer getShort() {
return 2;
}
@Override
public void doFilter(MyParam param, MyFilterChain filterChain, Integer index) {
System.out.println("Filter2");
if (param.getAmount().compareTo(start) > -1 && param.getAmount().compareTo(end) < 0) {
System.out.println("请发生短信验证码");
return;
}
filterChain.doFilter(param, filterChain, index);
}
}
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
@Service("Filter3")
public class Filter3 implements PrepareFilter {
public static final BigDecimal start = new BigDecimal("1000");
@Override
public Integer getShort() {
return 3;
}
@Override
public void doFilter(MyParam param, MyFilterChain filterChain, Integer index) {
System.out.println("Filter3");
if (param.getAmount().compareTo(start) > -1) {
System.out.println("扫脸");
return;
}
filterChain.doFilter(param, filterChain, index);
}
}
import com.zm.demo01.test.MyFilterChain;
import com.zm.demo01.test.MyParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zhou
*/
@Slf4j
@RestController
public class HelloController {
@Autowired
MyFilterChain myFilterChain;
@GetMapping("hello")
public String hello(MyParam param) {
myFilterChain.doFilter(param,myFilterChain,0);
log.info("1111111111111");
return "hello word update!";
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/133911.html