和钉钉请假一个道理,一层一层(层层处理)同意。
订单处理也类似,优惠券(满减、固定减)、物流、库存、支付。等等

实现方式一

  1. package com.example.demo.designMode;
  2. /**
  3. * 责任链
  4. * 请假决策-》 组长批准 -》 部门经理批准 -》副经理批准
  5. */
  6. public abstract class Approver {
  7. public Approver approver; //下一个节点
  8. public Approver setApprover(Approver approver){
  9. this.approver = approver;
  10. return this;
  11. }
  12. /**
  13. * 处理方法
  14. * @param day 请假天数
  15. * @return
  16. */
  17. public abstract Boolean checkOut(Integer day);
  18. }
  19. /**
  20. * 组长
  21. */
  22. class GroupApprover extends Approver{
  23. @Override
  24. public Boolean checkOut(Integer day) {
  25. if(day <2){
  26. System.out.println("组长通过请假!");
  27. return true;
  28. }else{
  29. System.out.println("组长通过请假!");
  30. return approver.checkOut(day);
  31. }
  32. }
  33. }
  34. /**
  35. * 部门经理
  36. */
  37. class DepartmentApprover extends Approver{
  38. @Override
  39. public Boolean checkOut(Integer day) {
  40. if(day <5){
  41. System.out.println("部门经理通过请假!");
  42. return true;
  43. }else{
  44. System.out.println("部门经理通过请假!");
  45. return approver.checkOut(day);
  46. }
  47. }
  48. }
  49. /**
  50. * 副经理
  51. */
  52. class VicePresidentApprover extends Approver{
  53. @Override
  54. public Boolean checkOut(Integer day) {
  55. if(day <10){
  56. System.out.println("副经理通过请假!");
  57. return true;
  58. }else{
  59. System.out.println("请假不通过,天数太长!");
  60. return false;
  61. }
  62. }
  63. }

测试:

  1. package com.example.demo.designMode;
  2. public class Test {
  3. public static void main(String[] args) {
  4. Approver approver = new GroupApprover()
  5. .setApprover(new DepartmentApprover()
  6. .setApprover(new VicePresidentApprover()));
  7. System.out.println(approver.checkOut(9));
  8. }
  9. }

实现方式二

  1. package com.example.demo.designMode;
  2. import java.util.function.Function;
  3. import java.util.function.Predicate;
  4. /**
  5. * 责任链2
  6. * 请假决策-》 组长批准 -》 部门经理批准 -》副经理批准
  7. */
  8. public abstract class Approver2 {
  9. public Approver2 nextHandler; //下一个节点
  10. public Predicate<Integer> predicate; //验证进入下个节点的方法
  11. public Approver2 setApprover2(Approver2 nextHandler){
  12. this.nextHandler = nextHandler;
  13. return this;
  14. }
  15. public final Boolean handleMessage(Integer day){
  16. if(predicate.test(day)){
  17. return checkOut(day);
  18. }else{
  19. if (this.nextHandler != null) {
  20. System.out.println("事情太严重,需报告上一级");
  21. return this.nextHandler.handleMessage(day);
  22. } else {
  23. System.out.println("我就是boss,没有上头");
  24. return false;
  25. }
  26. }
  27. }
  28. /**
  29. * 处理方法
  30. * @param day 请假天数
  31. * @return
  32. */
  33. public abstract Boolean checkOut(Integer day);
  34. }
  35. /**
  36. * 组长
  37. */
  38. class GroupApprover2 extends Approver2{
  39. {
  40. predicate = i ->i<2;
  41. }
  42. @Override
  43. public Boolean checkOut(Integer day) {
  44. System.out.println("组长通过请假!");
  45. return true;
  46. }
  47. }
  48. /**
  49. * 部门经理
  50. */
  51. class DepartmentApprover2 extends Approver2{
  52. {
  53. predicate = i ->i<5;
  54. }
  55. @Override
  56. public Boolean checkOut(Integer day) {
  57. System.out.println("组长通过请假!");
  58. return true;
  59. }
  60. }
  61. /**
  62. * 副经理
  63. */
  64. class VicePresidentApprover2 extends Approver2{
  65. {
  66. predicate = i ->i<10;
  67. }
  68. @Override
  69. public Boolean checkOut(Integer day) {
  70. System.out.println("副经理通过请假!");
  71. return true;
  72. }
  73. }

测试

  1. package com.example.demo.designMode;
  2. public class Test {
  3. public static void main(String[] args) {
  4. Approver2 approver2 = new GroupApprover2()
  5. .setApprover2(new DepartmentApprover2()
  6. .setApprover2(new VicePresidentApprover2()));
  7. System.out.println(approver2.handleMessage(9));
  8. }
  9. }

实现方式三 Springboot版本

  1. package com.example.designmode.designMode2;
  2. import org.springframework.stereotype.Component;
  3. import java.util.function.Predicate;
  4. /**
  5. * 责任链3
  6. * 请假决策-》 组长批准 -》 部门经理批准 -》副经理批准
  7. */
  8. @Component
  9. public abstract class SpringBootApprover {
  10. public Predicate<Integer> predicate; //验证进入下个节点的方法
  11. /**
  12. * 处理方法
  13. * @param day 请假天数
  14. * @return
  15. */
  16. public abstract Boolean checkOut(Integer day);
  17. }
  1. package com.example.designmode.designMode2;
  2. import org.springframework.core.annotation.Order;
  3. import org.springframework.stereotype.Service;
  4. /**
  5. * 组长
  6. */
  7. @Order(1)
  8. @Service
  9. public class GroupApproverImpl extends SpringBootApprover {
  10. {
  11. predicate = i ->i<2;
  12. }
  13. @Override
  14. public Boolean checkOut(Integer day) {
  15. System.out.println("组长通过请假!");
  16. return true;
  17. }
  18. }
  1. package com.example.designmode.designMode2;
  2. import org.springframework.core.annotation.Order;
  3. import org.springframework.stereotype.Service;
  4. /**
  5. * 部门经理
  6. */
  7. @Order(2)
  8. @Service
  9. public class DepartmentApproverImpl extends SpringBootApprover {
  10. {
  11. predicate = i ->i<5;
  12. }
  13. @Override
  14. public Boolean checkOut(Integer day) {
  15. System.out.println("组长通过请假!");
  16. return true;
  17. }
  18. }
  1. package com.example.designmode.designMode2;
  2. import org.springframework.core.annotation.Order;
  3. import org.springframework.stereotype.Service;
  4. /**
  5. * 副经理
  6. */
  7. @Order(3)
  8. @Service
  9. public class VicePresidentApproverImpl extends SpringBootApprover {
  10. {
  11. predicate = i ->i<10;
  12. }
  13. @Override
  14. public Boolean checkOut(Integer day) {
  15. System.out.println("副经理通过请假!");
  16. return true;
  17. }
  18. }
  1. package com.example.designmode.designMode2;
  2. import org.springframework.stereotype.Component;
  3. import javax.annotation.Resource;
  4. import java.util.List;
  5. /**
  6. * 增加流程控制方法
  7. */
  8. @Component
  9. public class XiangHandlerChain {
  10. @Resource
  11. private List<SpringBootApprover> approverList;
  12. //计数器,用来找到下一个节点
  13. public Integer index = 0;
  14. public final Boolean handleMessage(Integer day){
  15. if(approverList.get(index).predicate.test(day)){
  16. return approverList.get(index).checkOut(day);
  17. }else{
  18. index ++;
  19. if(index<approverList.size()){
  20. System.out.println("事情太严重,需报告上一级");
  21. return handleMessage(day);
  22. } else {
  23. System.out.println("我就是boss,没有上头");
  24. return false;
  25. }
  26. }
  27. }
  28. }

测试

  1. package com.example.designmode;
  2. import com.example.designmode.designMode2.XiangHandlerChain;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import javax.annotation.Resource;
  6. @SpringBootTest
  7. class DesignmodeApplicationTests {
  8. @Resource
  9. XiangHandlerChain xiangHandlerChain;
  10. @Test
  11. void contextLoads() {
  12. xiangHandlerChain.handleMessage(10);
  13. }
  14. }

实现方式四:Servlet拦截器Filter

  1. package javax.servlet;
  2. import java.io.IOException;
  3. public interface Filter {
  4. //初始化方法
  5. public void init(FilterConfig filterConfig) throws ServletException;
  6. //主方法
  7. public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException;
  8. //销毁
  9. public void destroy();
  10. }
  1. package javax.servlet;
  2. import java.io.IOException;
  3. public interface FilterChain {
  4. public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;
  5. }

通常我们实现的过滤器

  1. package com.xiang.filter;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. /**
  5. *
  6. */
  7. public class MyFilter implements Filter {
  8. //初始化
  9. public void init(FilterConfig filterConfig) throws ServletException {
  10. System.out.println("初始化");
  11. }
  12. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  13. request.setCharacterEncoding("utf-8");
  14. response.setCharacterEncoding("utf-8");
  15. response.setContentType("text/html;charset=UTF-8");
  16. chain.doFilter(request,response);
  17. }
  18. //销毁
  19. public void destroy() {
  20. }
  21. }

下面是模拟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);
    }
}