和钉钉请假一个道理,一层一层(层层处理)同意。
订单处理也类似,优惠券(满减、固定减)、物流、库存、支付。等等
实现方式一
package com.example.demo.designMode;/*** 责任链* 请假决策-》 组长批准 -》 部门经理批准 -》副经理批准*/public abstract class Approver {public Approver approver; //下一个节点public Approver setApprover(Approver approver){this.approver = approver;return this;}/*** 处理方法* @param day 请假天数* @return*/public abstract Boolean checkOut(Integer day);}/*** 组长*/class GroupApprover extends Approver{@Overridepublic Boolean checkOut(Integer day) {if(day <2){System.out.println("组长通过请假!");return true;}else{System.out.println("组长通过请假!");return approver.checkOut(day);}}}/*** 部门经理*/class DepartmentApprover extends Approver{@Overridepublic Boolean checkOut(Integer day) {if(day <5){System.out.println("部门经理通过请假!");return true;}else{System.out.println("部门经理通过请假!");return approver.checkOut(day);}}}/*** 副经理*/class VicePresidentApprover extends Approver{@Overridepublic Boolean checkOut(Integer day) {if(day <10){System.out.println("副经理通过请假!");return true;}else{System.out.println("请假不通过,天数太长!");return false;}}}
测试:
package com.example.demo.designMode;public class Test {public static void main(String[] args) {Approver approver = new GroupApprover().setApprover(new DepartmentApprover().setApprover(new VicePresidentApprover()));System.out.println(approver.checkOut(9));}}
实现方式二
package com.example.demo.designMode;import java.util.function.Function;import java.util.function.Predicate;/*** 责任链2* 请假决策-》 组长批准 -》 部门经理批准 -》副经理批准*/public abstract class Approver2 {public Approver2 nextHandler; //下一个节点public Predicate<Integer> predicate; //验证进入下个节点的方法public Approver2 setApprover2(Approver2 nextHandler){this.nextHandler = nextHandler;return this;}public final Boolean handleMessage(Integer day){if(predicate.test(day)){return checkOut(day);}else{if (this.nextHandler != null) {System.out.println("事情太严重,需报告上一级");return this.nextHandler.handleMessage(day);} else {System.out.println("我就是boss,没有上头");return false;}}}/*** 处理方法* @param day 请假天数* @return*/public abstract Boolean checkOut(Integer day);}/*** 组长*/class GroupApprover2 extends Approver2{{predicate = i ->i<2;}@Overridepublic Boolean checkOut(Integer day) {System.out.println("组长通过请假!");return true;}}/*** 部门经理*/class DepartmentApprover2 extends Approver2{{predicate = i ->i<5;}@Overridepublic Boolean checkOut(Integer day) {System.out.println("组长通过请假!");return true;}}/*** 副经理*/class VicePresidentApprover2 extends Approver2{{predicate = i ->i<10;}@Overridepublic Boolean checkOut(Integer day) {System.out.println("副经理通过请假!");return true;}}
测试
package com.example.demo.designMode;public class Test {public static void main(String[] args) {Approver2 approver2 = new GroupApprover2().setApprover2(new DepartmentApprover2().setApprover2(new VicePresidentApprover2()));System.out.println(approver2.handleMessage(9));}}
实现方式三 Springboot版本
package com.example.designmode.designMode2;import org.springframework.stereotype.Component;import java.util.function.Predicate;/*** 责任链3* 请假决策-》 组长批准 -》 部门经理批准 -》副经理批准*/@Componentpublic abstract class SpringBootApprover {public Predicate<Integer> predicate; //验证进入下个节点的方法/*** 处理方法* @param day 请假天数* @return*/public abstract Boolean checkOut(Integer day);}
package com.example.designmode.designMode2;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Service;/*** 组长*/@Order(1)@Servicepublic class GroupApproverImpl extends SpringBootApprover {{predicate = i ->i<2;}@Overridepublic Boolean checkOut(Integer day) {System.out.println("组长通过请假!");return true;}}
package com.example.designmode.designMode2;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Service;/*** 部门经理*/@Order(2)@Servicepublic class DepartmentApproverImpl extends SpringBootApprover {{predicate = i ->i<5;}@Overridepublic Boolean checkOut(Integer day) {System.out.println("组长通过请假!");return true;}}
package com.example.designmode.designMode2;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Service;/*** 副经理*/@Order(3)@Servicepublic class VicePresidentApproverImpl extends SpringBootApprover {{predicate = i ->i<10;}@Overridepublic Boolean checkOut(Integer day) {System.out.println("副经理通过请假!");return true;}}
package com.example.designmode.designMode2;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.List;/*** 增加流程控制方法*/@Componentpublic class XiangHandlerChain {@Resourceprivate List<SpringBootApprover> approverList;//计数器,用来找到下一个节点public Integer index = 0;public final Boolean handleMessage(Integer day){if(approverList.get(index).predicate.test(day)){return approverList.get(index).checkOut(day);}else{index ++;if(index<approverList.size()){System.out.println("事情太严重,需报告上一级");return handleMessage(day);} else {System.out.println("我就是boss,没有上头");return false;}}}}
测试
package com.example.designmode;import com.example.designmode.designMode2.XiangHandlerChain;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;@SpringBootTestclass DesignmodeApplicationTests {@ResourceXiangHandlerChain xiangHandlerChain;@Testvoid contextLoads() {xiangHandlerChain.handleMessage(10);}}
实现方式四:Servlet拦截器Filter
package javax.servlet;import java.io.IOException;public interface Filter {//初始化方法public void init(FilterConfig filterConfig) throws ServletException;//主方法public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException;//销毁public void destroy();}
package javax.servlet;import java.io.IOException;public interface FilterChain {public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;}
通常我们实现的过滤器
package com.xiang.filter;import javax.servlet.*;import java.io.IOException;/****/public class MyFilter implements Filter {//初始化public void init(FilterConfig filterConfig) throws ServletException {System.out.println("初始化");}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=UTF-8");chain.doFilter(request,response);}//销毁public void destroy() {}}
下面是模拟Tomcat实现,使用了观察者模式
private static class TomcatChain implements FilterChain {
private final List<? extends Filter> additionalFilters;
private int currentPosition = 0;
public TomcatChain(List<? extends Filter> additionalFilters) {
this.additionalFilters = additionalFilters;
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response)
throws IOException, ServletException {
this.currentPosition++;
Filter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}
