用最最通俗易懂的例子来谈责任链模式
作者:互联网
责任链模式是什么呢?
责任链模式就是多个处理对象连成链处理单个请求,可能每个处理对象都处理,也可能都不处理。如果要用代码来说就是一个接口,多个实现类而这些处理方式链接成链,诶这就是责任链模式!
用两个例子来深刻理解责任链模式
第一个例子就是请假流程,来瞅瞅流程图
申请人实体类
/**
* @author: tianjx
* @date: 2022/1/13 20:58
* @description: 请假申请人
*/
public class Leave {
// 请假人姓名
private String name;
// 请假天数
private int days;
public Leave() {
}
public Leave(String name, int days) {
this.name = name;
this.days = days;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDays() {
return days;
}
public void setDays(int days) {
this.days = days;
}
@Override
public String toString() {
return "Leave{" +
"name='" + name + '\'' +
", days='" + days + '\'' +
'}';
}
}
处理抽象类(包含设置下一个人的方法)
/**
* @author: tianjx
* @date: 2022/1/13 21:00
* @description: 请假审批抽象类
*/
public abstract class LeaveHandler {
// 需要总经理批准的审批天数
protected int MANAGER_LEAVE_DAYS = 3;
// 领导名称
private String name;
// 审批意见
private boolean approved;
// 下一个审批人
protected LeaveHandler nextLeaveHandler;
// 需要子类实现的具体方法
public abstract void handle(Leave request);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean getApproved() {
return approved;
}
public void setApproved(boolean approved) {
this.approved = approved;
}
public LeaveHandler getNextLeaveHandler() {
return nextLeaveHandler;
}
public LeaveHandler setNextLeaveHandler(LeaveHandler nextLeaveHandler) {
this.nextLeaveHandler = nextLeaveHandler;
return nextLeaveHandler;
}
public int getMANAGER_LEAVE_DAYS(){
return MANAGER_LEAVE_DAYS;
}
public LeaveHandler(String name) {
this.name = name;
}
}
项目经理处理类
/**
* @author: tianjx
* @date: 2022/1/13 21:09
* @description: 项目经理审批
*/
public class ProjectManagerHandler extends LeaveHandler{
public ProjectManagerHandler(String name){
super(name);
}
@Override
public void handle(Leave request) {
if (this.getApproved() == true){
System.out.println(this.getName() + "审批通过!" + request.toString());
if (this.nextLeaveHandler != null){
this.nextLeaveHandler.handle(request);
}
}else{
System.out.println(this.getName() + "审批拒绝!" + request.toString());
}
}
}
项目总监处理类
/**
* @author: tianjx
* @date: 2022/1/13 21:14
* @description: 项目总监审批
*/
public class ProjectDirectorHandler extends LeaveHandler{
public ProjectDirectorHandler(String name){
super(name);
}
@Override
public void handle(Leave request) {
if (this.getApproved() == true){
System.out.println(this.getName() + "审批通过!" + request.toString());
if (this.nextLeaveHandler != null && request.getDays() > this.getMANAGER_LEAVE_DAYS()){
this.nextLeaveHandler.handle(request);
}
}else{
System.out.println(this.getName() + "审批拒绝!" + request.toString());
}
}
}
总经理处理类
/**
* @author: tianjx
* @date: 2022/1/13 21:17
* @description: 总经理审批
*/
public class MangerLeaveHandler extends LeaveHandler{
public MangerLeaveHandler(String name){
super(name);
}
@Override
public void handle(Leave request) {
if (this.getApproved() == true){
System.out.println(this.getName() + "审批通过!" + request.toString());
if (this.nextLeaveHandler != null){
this.nextLeaveHandler.handle(request);
}
}else{
System.out.println(this.getName() + "审批拒绝!" + request.toString());
}
}
}
测试demo
/**
* @author: tianjx
* @date: 2022/1/13 21:18
* @description:
*/
public class LeaveDemo {
public static void main(String[] args) {
Leave zs = new Leave("张三",4);
Leave ls = new Leave("李四",2);
ProjectManagerHandler projectManagerHandler = new ProjectManagerHandler("项目经理");
ProjectDirectorHandler projectDirectorHandler = new ProjectDirectorHandler("项目总监");
MangerLeaveHandler mangerLeaveHandler = new MangerLeaveHandler("总经理");
// 设置责任链
projectManagerHandler.setNextLeaveHandler(projectDirectorHandler).setNextLeaveHandler(mangerLeaveHandler);
projectManagerHandler.setApproved(true);
projectDirectorHandler.setApproved(true);
mangerLeaveHandler.setApproved(false);
projectManagerHandler.handle(zs);
System.out.println("---------------------------");
projectManagerHandler.setApproved(true);
projectDirectorHandler.setApproved(false);
projectManagerHandler.handle(ls);
}
}
第二个例子就是支付金额例子
如果支付金额小于200,免密支付
201-10000,支付密码
10001-100000,短信验证
100001以上扫脸支付!
订单金额实体类
/**
* @author: tianjx
* @date: 2022/1/13 21:49
* @description: 订单实体类
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Order {
private BigDecimal amount;
}
责任链管理类
/**
* @author: tianjx
* @date: 2022/1/13 21:59
* @description: 责任链管理器
*/
@Component
public class FilterChain implements ApplicationContextAware, PaymentHandler {
// 存储所有的处理器
List<PaymentHandler> paymentHandlerList;
@Override
public int getIndex() {
return 0;
}
@Override
public void doFilter(Order order, FilterChain filterChain,Integer count) {
count = count + 1;
if (count <= paymentHandlerList.size()){
paymentHandlerList.get(count - 1).doFilter(order, filterChain, count);
}else{
System.out.println("免密支付!");
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, PaymentHandler> handlerMap = applicationContext.getBeansOfType(PaymentHandler.class);// 获取所有的处理器
paymentHandlerList = new ArrayList<>(handlerMap.values());
paymentHandlerList = paymentHandlerList.stream()
.sorted(Comparator.comparing(PaymentHandler::getIndex))// 根据index排序
.collect(Collectors.toList());// 转换成集合
}
}
责任链接口
/**
* @author: tianjx
* @date: 2022/1/13 21:52
* @description: 订单金额接口
*/
@Component
public interface PaymentHandler {
int getIndex();
/**
*
* @param order 订单实体类
* @param filterChain 责任链管理器
* @param count 根据index来判断执行了几个
*/
void doFilter(Order order,FilterChain filterChain,Integer count);
}
责任链实现类
/**
* @author: tianjx
* @date: 2022/1/13 21:54
* @description: 密码支付
*/
@Component
public class MmPaymentHandler implements PaymentHandler {
@Override
public int getIndex() {
return 1;
}
@Override
public void doFilter(Order order, FilterChain filterChain, Integer count) {
if (order.getAmount().compareTo(BigDecimal.valueOf(201)) == 1 && order.getAmount().compareTo(BigDecimal.valueOf(10000)) == -1){
System.out.println("请输入密码!");
return;
}
filterChain.doFilter(order, filterChain, count);
}
}
/**
*
* @author: tianjx
* @date: 2022/1/13 22:15
* @description:
*/
@Component
public class SmsPaymentHandler implements PaymentHandler{
@Override
public int getIndex() {
return 2;
}
@Override
public void doFilter(Order order, FilterChain filterChain, Integer count) {
if (order.getAmount().compareTo(BigDecimal.valueOf(10001)) == 1 && order.getAmount().compareTo(BigDecimal.valueOf(100000)) == -1){
System.out.println("短信验证码支付!");
return;
}
filterChain.doFilter(order, filterChain, count);
}
}
/**
* @author: tianjx
* @date: 2022/1/13 22:18
* @description:
*/
@Component
public class FacePaymentHandler implements PaymentHandler{
@Override
public int getIndex() {
return 3;
}
@Override
public void doFilter(Order order, FilterChain filterChain, Integer count) {
if (order.getAmount().compareTo(BigDecimal.valueOf(100001)) == 1){
System.out.println("请刷脸支付!");
return;
}
filterChain.doFilter(order, filterChain, count);
}
}
测试demo
@SpringBootTest
class DemoApplicationTests {
@Autowired
FilterChain filterChain;
@Test
void testChain(){
Order order1 = new Order(BigDecimal.valueOf(99));
Order order2 = new Order(BigDecimal.valueOf(299));
Order order3 = new Order(BigDecimal.valueOf(19988));
Order order4 = new Order(BigDecimal.valueOf(119988));
filterChain.doFilter(order1, filterChain, 0);
filterChain.doFilter(order2, filterChain, 0);
filterChain.doFilter(order3, filterChain, 0);
filterChain.doFilter(order4, filterChain, 0);
}
}
谈谈责任链模式的优缺点及总结
优点的话,不用说朋友们就知道我要说啥了,从设计原则(设计原则看这篇就够了)上说,因为每个实现类的职责明确且单一所以符合单一职责原则,我们也是面向接口编程,符合依赖倒置原则,而且我们设计接口也是尽量小而精所以也符合接口隔离原则,如果我们添加新的需求只要扩展类就行了,源代码改动比较小也符合开闭原则,这这这应该很棒棒了!
缺点的话,其实如果不懂责任链模式的话其他人来看还是有点生涩的,并且有时候重写接口的话所有子类可能都要修改!
总结一下,责任链模式其实比较常用,我们用的spring的过滤器,拦截器都用到了责任链模式,如果有类似过滤器,请假,金额大小的例子我们可以尝试应用一下!
感谢大家的阅读,我是Alson_Code
标签:最最,return,name,void,通俗易懂,order,public,filterChain,来谈 来源: https://blog.csdn.net/weixin_42415173/article/details/122484586