Java设计模式:责任链模式+适配者模式+工厂模式+模版方法模式 结合spring使用

161 阅读6分钟

责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理它。

什么是责任链模式?

责任链模式的核心思想是将多个对象组成一条链,并沿着这条链传递请求,直到有一个对象能够处理该请求。每个对象都有自己的处理逻辑以及对下一个处理者的引用,当收到请求后,它可以选择自行处理或者将请求传递给下一个处理者。

SpringCloud Gateway 中责任链的使用

在上篇文章中记录了 SpringCloud Gateway中过滤器使用了适配者模式,其实当所有过滤器适配处理之后,会把所有的过滤器传给一个过滤器链 DefaultGatewayFilterChain(FilteringWebHandler类中的内部静态类),并通过滤器链执去行过滤逻辑,如下:


private static class DefaultGatewayFilterChain implements GatewayFilterChain {

  private final int index;

  private final List<GatewayFilter> filters;

  DefaultGatewayFilterChain(List<GatewayFilter> filters) {
   this.filters = filters;
   this.index = 0;
  }

  private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
   this.filters = parent.getFilters();
   this.index = index;
  }

  public List<GatewayFilter> getFilters() {
   return filters;
  }

  @Override
  public Mono<Void> filter(ServerWebExchange exchange) {
            // 执行过滤链
   return Mono.defer(() -> {
    if (this.index < filters.size()) {
     GatewayFilter filter = filters.get(this.index);
     DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
     return filter.filter(exchange, chain);
    }
    else {
     return Mono.empty(); // complete
    }
   });
  }

 }

责任链模式+适配者模式+工厂模式 结合spring使用例子

参考网关逻辑,实现过滤逻辑

定义过滤器接口和实现

/**
 * 过滤接口对象
 *
 * @author LGC
 */
public interface MyFilter {

    void filter(ChainExchange exchange, FilterChain filterChain);

}

/**
 * @author LGC
 */
@Component
public class AMyFilter implements MyFilter, Ordered {

    @Override
    public void filter(ChainExchange exchange, FilterChain filterChain) {
        System.out.println("A filter order 1 do");
        filterChain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

/**
 * @author LGC
 */
@Component
public class BMyFilter implements MyFilter, Ordered {

    @Override
    public void filter(ChainExchange exchange, FilterChain filterChain) {
        System.out.println("B filter order 2 do");
        filterChain.filter(exchange);
    }


    @Override
    public int getOrder() {
        return 2;
    }
}

/**
 * @author LGC
 */
@Component
public class CMyFilter implements MyFilter {

    @Override
    public void filter(ChainExchange exchange, FilterChain filterChain) {
        System.out.println("C filter no order do");
        filterChain.filter(exchange);
    }

}

定义过滤器实现排序接口适配器

/**
 * 适配器
 * 转换成排序的过滤器
 *
 * @author LGC
 */
public class OrderedMyFilterAdapter implements MyFilter, Ordered {

    private final MyFilter delegate;

    private final int order;

    public OrderedMyFilterAdapter(MyFilter delegate, int order) {
        this.delegate = delegate;
        this.order = order;
    }

    @Override
    public void filter(ChainExchange exchange, FilterChain filterChain) {
        this.delegate.filter(exchange, filterChain);
    }

    @Override
    public int getOrder() {
        return this.order;
    }
}

定义过滤器链数据交换中心

/**
 * 过滤链交换信息 可保存一下过滤器需要的一些信息
 *
 * @author LGC
 */
public interface ChainExchange {

    void put(Object key, Object value);

    <T> T get(Object key);

    @Nullable
    ApplicationContext getApplicationContext();

}

/**
 * 默认链条数据交换
 *
 * @author LGC
 */
public class DefaultChainExchange implements ChainExchange {

    @Nullable
    private final ApplicationContext applicationContext;

    private final Map<Object, Object> attributes = new ConcurrentHashMap<>();


    public DefaultChainExchange(@Nullable ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public void put(Object key, Object value) {
        attributes.put(key, value);
    }

    @Override
    public <T> T get(Object key) {
        return (T) attributes.get(key);
    }


    @Override
    public ApplicationContext getApplicationContext() {
        return this.applicationContext;
    }
}

工厂方法模式创建过滤链

/**
 * 过滤器链工厂
 *
 * @author LGC
 */
public interface FilterChainFactory {
    FilterChain create();
}

/**
 * @author LGC
 */
public abstract class AbstractFilterChainFactory implements FilterChainFactory, ApplicationContextAware {

    private ApplicationContext applicationContext;

    private List<MyFilter> filters = new ArrayList<>();


    @Override
    public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
        // 在容器进行属性赋值后,执行 aware 相关回调
        this.applicationContext = applicationContext;
    }

    /**
     * 加载所有过滤器
     *
     * @return
     */
    public List<MyFilter> loadFilter() {
        if (filters.size() > 0) {
            return filters;
        }
        Collection<MyFilter> values = applicationContext.getBeansOfType(MyFilter.class).values();
        filters = values.stream().map(filter -> {
            if (filter instanceof Ordered) {
                int order = ((Ordered) filter).getOrder();
                return new OrderedMyFilterAdapter(filter, order);
            }
            return filter;
        }).collect(Collectors.toList());
        return filters;
    }
}

/**
 * @author LGC
 */
@Component
public class MyFilterChainFactory extends AbstractFilterChainFactory {

    @Override
    public FilterChain create() {
        // 从容器中加载所有的过滤器
        List<MyFilter> filters = loadFilter();
        // 排序 摘自 gateway 网关 FilteringWebHandler -> DefaultGatewayFilterChain
        // 这个可过滤需要执行的handler 逻辑
        AnnotationAwareOrderComparator.sort(filters);
        return new MyFilterChain(filters);
    }
}

/**
 * @author LGC
 */
public interface FilterChain {

    /**
     * @param exchange 过滤链数据交换
     */
    void filter(ChainExchange exchange);

}

/**
 * 过滤器
 * 参考 Gateway  GatewayFilterChain
 *
 * @author LGC
 */
public class MyFilterChain implements FilterChain {
    /**
     * 所有过滤器
     */
    private final List<MyFilter> filters;
    /**
     * 当前过滤器下标
     */
    private final Integer index;

    public MyFilterChain(List<MyFilter> filters) {
        this.filters = filters;
        this.index = 0;
    }

    private MyFilterChain(MyFilterChain parent, Integer index) {
        this.filters = parent.getFilters();
        this.index = index;
    }

    public List<MyFilter> getFilters() {
        return filters;
    }

    @Override
    public void filter(ChainExchange exchange) {
        if (this.index < filters.size()) {
            MyFilter myFilter = filters.get(index);
            myFilter.filter(exchange, new MyFilterChain(this, this.index + 1));
        } else {
            System.out.println("过滤链执行完毕....");
        }
    }
}

测试

/**
 * @author LGC
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LaboratoryApplication.class)
public class MyFilterChainPatternTest {

    @Resource
    private FilterChainFactory filterChainFactory;

    @Resource
    private ApplicationContext applicationContext;

    @Test
    public void chainTest() {
        // 构建过滤链交换器,用于过滤器直接存储数据用
        ChainExchange chainExchange = new DefaultChainExchange(applicationContext);
        // 工厂创建过滤链-把过滤器从容器中获取-并进行排序
        FilterChain filterChain = filterChainFactory.create();
        filterChain.filter(chainExchange);

    }
}
//    输出
//    A filter order 1 do
//    B filter order 2 do
//    C filter no order do
//    过滤链执行完毕....

**上面只完成了简单的拦截链逻辑,其实我们调用完过滤链后,可以定义执行我们具体的业务逻辑。假如有一个会员卡支付扣除余额并通知的业务,过滤链则可以是支付前各种复杂的校验,过滤链执行通过后,执行会员卡扣除余额等一系列操作则为具体的业务逻辑。修改一下我们的实现:

升级

修改过滤链和过滤器实现

主要是加了一个参数 Consumer consumer, 用作过滤链执行后操作逻辑

/**
 * 过滤器
 * 参考 Gateway  GatewayFilterChain
 *
 * @author LGC
 */
public class MyFilterChain implements FilterChain {
    /**
     * 所有过滤器
     */
    private final List<MyFilter> filters;
    /**
     * 当前过滤器下标
     */
    private final Integer index;

    public MyFilterChain(List<MyFilter> filters) {
        this.filters = filters;
        this.index = 0;
    }

    private MyFilterChain(MyFilterChain parent, Integer index) {
        this.filters = parent.getFilters();
        this.index = index;
    }

    public List<MyFilter> getFilters() {
        return filters;
    }

    @Override
    public void filter(ChainExchange exchange, Consumer<ChainExchange> consumer) {
        if (this.index < filters.size()) {
            MyFilter myFilter = filters.get(index);
            myFilter.filter(exchange, new MyFilterChain(this, this.index + 1), consumer);
        } else {
            System.out.println("过滤链执行完毕....");
            consumer.accept(exchange);
        }
    }
}

/**
 * @author LGC
 */
@Component
public class AMyFilter implements MyFilter, Ordered {

    @Override
    public void filter(ChainExchange exchange, FilterChain filterChain, Consumer<ChainExchange> consumer) {
        System.out.println("A filter order 1 do 校验1");
        filterChain.filter(exchange, consumer);
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
// 其它修改类....

定义支付业务处理Handler

采用模版方法设计模式,统一入口执行过滤链,和执行具体支付逻辑

/**
 * 订单处理handler
 *
 * @author LGC
 */
public interface OrderHandler {
    void handle(ChainExchange chainExchange);
}

/**
 * 模版方法设计模式
 *
 * @author LGC
 */
public abstract class AbstractOrderHandler implements OrderHandler {

    @Override
    public void handle(ChainExchange chainExchange) {
        // 执行过滤链
        FilterChainFactory factory = chainExchange.get(FilterChainFactory.class);
        FilterChain filterChain = factory.create();
        filterChain.filter(chainExchange, this::onHandle);
    }

    /**
     * 执行过滤链后具体逻辑 handle
     *
     * @param chainExchange
     */
    public abstract void onHandle(ChainExchange chainExchange);

}

/**
 * 订单支付handler
 *
 * @author LGC
 */
@Component
public class OrderPayHandler extends AbstractOrderHandler {

    @Override
    public void onHandle(ChainExchange chainExchange) {
  //chainExchange.get(OrderInfo.Class)
        System.out.println("获取订单信息,完成订单支付逻辑...");
        //
    }
}

升级后测试

通过支付handler执行支付流程

/**
 * @author LGC
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LaboratoryApplication.class)
public class MyFilterChainPatternTest {

    @Resource
    private FilterChainFactory filterChainFactory;

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private OrderHandler orderHandler;

    @Test
    public void chainTest() {
        // 构建过滤链交换器,用于过滤器直接存储数据用
        ChainExchange chainExchange = new DefaultChainExchange(applicationContext);
        chainExchange.put(FilterChainFactory.class, filterChainFactory);
        orderHandler.handle(chainExchange);
  // 发送通知
    }
}

//    输出
//    A filter order 1 do 校验1
//    B filter order 2 do 校验2
//    C filter no order do
//    过滤链执行完毕....
//    获取订单信息,完成订单支付逻辑...

从输出结果可知,当执行完过滤链后,会执行订单支付的逻辑。其实还有很多优化的地方,比如下单可以有很多种支付方式,不同商品类目可能只支持某些支付方式,我们可以通过适配者模式,找出商品类目所支持的支付方式,再根据下单时选择的支付方式,获取适配的支付Handler执行支付。同时我们也可以加入重试机制,不同的支付方式可以配置不同的重试策略,所有可以优化的地方点还有很多

结语

责任链模式能够降低请求发送者和接收者之间的耦合度,使得系统更灵活、可扩展