美文网首页Java成长之路
我在项目内使用了设计模式后,同事直呼看不懂

我在项目内使用了设计模式后,同事直呼看不懂

作者: Java古德 | 来源:发表于2020-09-18 10:37 被阅读0次

一切抛开业务的设计,都是扯淡!在项目中有个我们会对多个接口进行多业务逻辑判断,项目开始工期紧,所以先以实现功能为主,最近打算优化一番,一开始的代码是这样的

public void checkProjectAdd(List<OrderDetail> list) {
        if (!CollectionUtils.isEmpty(list)) {
            orderService.check(list);
            stockService.check(list);
            orderAddress.check(list);
            userScoreService.check(list);
            activityService.check(list);
            this.check();
        }
        excute();
    }

虽然对检查类的方法做了简单的封装,但在好多地方可能会存在重复的判断,比如订单提交,加入购物车等等,冗余代码随处可见,且不易扩展。在此情形下,废话不多说,准备开干,先来分析分析业务,因为我们的各个检查接口的处理原则是要保证顺序性的,而在检查的过程中可能根据商品提交参数而实质去动态改变list参数中的内容,比如一个库存当两个卖,用户会员等级结合实际商品数判断能否享受折扣等等,所以每一级的检查或手动处理值都是要求检查类代码<u>执行顺序</u>,思前想后,想起曾在阅读mybatis源码时觉得其设计的plugins模式很适合此类场景,于是决定使用《责任链模式》来进行这一次代码的优化。

首先简单介绍一下什么是责任链,说到链,大家就能想到链表,这里我们只说最简单的链表(单向链表)

单向链表就是当前对象内存储着下一个对象的引用地址,责任链模式的概念也描述下:

<u>责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。</u>

概念都是标准,一般都很难理解是什么意思,我们拿图说事

这每一层都是大哥,想要跨过难关还是不太容易呀。但是没办法为了要干真正的实事还是要一关一关闯的,接下来我们要开始进行包装,AOP大家都知道(面向切面),既然我们最终的提交方法是excute,那切面就是excute了,在切面之前如何执行自定义的Interceptor(拦截器)呢?这里我<typo id="typo-1168" data-origin="是用" ignoretag="true">是用</typo>的是jdk动态代理模式,动态代理,不太了解的看这里(JDK动态代理),使用动态代理的好处是我们可以对成百上千个已知与将来可能要编写的接口进行包装,比如我的订单提交事件叫做submitOrder,加入购车addCart,我都可以通过我的代理模式对这些接口进行包装,在代理模式中我规定好Interceptor,这样就能统一了

通过一级一级的代理模型,最终我们才能真正调用到IOrderService的具体实现上,废话不多说,开始撸代码

首先定义好我们自己拦截器类

public interface Interceptor {
    Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException;
}

接下来代理工厂:

public class ProxyFactory implements InvocationHandler {

    private Object target;
    private Interceptor interceptor;

    private ProxyFactory(Object target, Interceptor interceptor) {
        this.target = target;
        this.interceptor = interceptor;
    }

    public static Object wrap(Object target, Interceptor filter) {

        ProxyFactory proxyFactory = new ProxyFactory(target, filter);
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), proxyFactory);

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Invocation invocation = new Invocation(target, method, args);
        return interceptor.intercept(invocation);
    }

}

代理工厂主要就是对目标对象target进行包装,这里的target可能是原对象,也有可能是包装过后代理对象二次包装代理,简单来说是这样,我们的IOrderService中的submitOrder方法,在托管给JDK动态代理后,为了实现责任链的链式原则,我们会基于此对象再次调用wrap方法进行二次包装,将我们的各式各样的拦截器一层一层的包装上去,这样处理成上一级引用下一级的链式关系。

接下来定义我们具体都<typo id="typo-2570" data-origin="又" ignoretag="true">又</typo>那些拦截器大哥

public class TodoInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
        System.out.println(" todo something ");
        Object result = invocation.proceed();
        System.out.println(" to do end something ");
        return result;
    }
}

public class LogInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
        System.out.println(" do log ");
        Object result = invocation.proceed();
        System.out.println(" do log ");
        return result;
    }
}

两位拦路大哥已再此,接下来我们吧拦路大哥们放入工厂进行包装

<pre language="javascript" code_block="true">    @Override
    public void checkSubmitOrder() {
        IOrderService orderService = new OrderService();
        orderService = (IOrderService) ProxyFactory.wrap(orderService, new LogInterceptor());
        orderService = (IOrderService) ProxyFactory.wrap(orderService, new TodoInterceptor());
        orderService.submitOrder();
    }

代码执行效果如下

例子挺简单的,主要是说明责任链可以使用的场景,结合此责任链的扩展就非常多了,例如我把拦截器统一交给spring 托管,在每个检查方法上自定义注解,标记需要执行的拦截器,在AOP切面扫描业务方法时,判断是否存在此类责任链的拦截注解,有的话则执行业务判断,这样子就统一了业务检查代码的封装,再也不用再每行代码里写那些重复的chek()了,介于篇幅,就<typo id="typo-3836" data-origin="不在" ignoretag="true">不在</typo>过多介绍了,有兴趣可以私聊我。

我是tom:一切的恐惧都源于自己的未知。

相关文章

  • 我在项目内使用了设计模式后,同事直呼看不懂

    一切抛开业务的设计,都是扯淡!在项目中有个我们会对多个接口进行多业务逻辑判断,项目开始工期紧,所以先以实现功能为主...

  • 架构师 - 设计模式 (UML工具)

    设计模式 设计模式在项目中的优势使项目结构变得清晰便于项目维护 使用设计模式, 旨在编写 可复用, 方便维护的代码...

  • iOS-MVC

    有这么一个说法——设计模式。设计模式包括单例、代理、通知。 使用设计模式可以使项目的架构层次更加清晰,使项目模式化...

  • MVP模式简单易懂的介绍方式

    AndroidMVP模式[1]也不是什么新鲜的东西了,我在自己的项目里也普遍地使用了这个设计模式。当项目越来越庞大...

  • 设计模式之状态模式

    开始总结设计模式主要是因为项目在实际的使用中,适合的设计模式能够使代码变得更加优雅,也更便于维护。各种设计模式的精...

  • UI(十一)MVC(自定义cell)

    设计模式:单例代理通知 《观察者》mvc门面工厂 使用设计模式->可以使项目的架构层次更加清晰使项目模式化容易管理...

  • 你架构中使用了什么设计模式?

    总是被面试官问道你在项目中用到了什么设计模式,之前是在自己写的ImageLoader中对缓存用了设计模式,但是由于...

  • 闲来无事,贴zuul框架下的一个类的源码

    对于初学设计模式的小伙伴,试看下,这里使用了哪些设计模式 饿汉式单例 工厂方法 自己在使用容器做进程内缓存的时候,...

  • Python 3.10 正式发布,新增模式匹配,同事用了直呼真香

    前几天,也就是 10 月 4 日,Python 发布了 3.10.0 版本,什么?3.9 之后居然不是 4.0?(...

  • Tomcat中设计模式

    1 Tomcat中设计模式 在Tomcat中用了很多设计模式,如模板模式、工厂模式和单例模式等一些常用的设计模式,...

网友评论

    本文标题:我在项目内使用了设计模式后,同事直呼看不懂

    本文链接:https://www.haomeiwen.com/subject/stgdyktx.html