美文网首页
Java里面可以像JS那样写回调方法吗?

Java里面可以像JS那样写回调方法吗?

作者: 程就人生 | 来源:发表于2020-12-21 22:40 被阅读0次

    问题描述:

    在某一个页面,有一个按钮a,点击按钮a,调用接口A,请求参数3个,返回参数5个;在另一个页面,有一个按钮b,点击按钮b,调用接口B,请求参数4个,返回参数5个;来自不同页面的两个按钮,看似不相关,请求参数不一样,但是在后台的业务逻辑处理上,却有百分之九十的代码是一样的,还有百分之十,是处理一个不同的类,在返回值上,也仅有这一个类不一样。

    那么这样的接口该如何写呢?

    解决方法一:
    这是最笨的方法,A接口的业务逻辑单独处理;写完A接口,写B接口时,发现和A接口有百分之九十的相似,那好办,把A接口的代码拷贝一份,把不一样的地方改一改,OK了。

    如果A、B接口分别由不同的人写时,就会出现两种风格的代码。A、B接口的业务逻辑处理是分开的,各自处理各自的,该公共的没公共。

    这样的问题很明显,代码不够精简,后期维护成本高。

    解决方法二:
    把A、B接口业务处理逻辑一样的代码,提取出来,作为一个公共的方法调用,调用完公共的代码后,根据处理结果的返回值,再处理最后百分之十不一样的地方。

    这样写的好处很明显,代码精简,后期维护成本低,代码更优质,而实际上是怎么处理的呢?

    负责这两个接口的同事是同一位,他先写好了A接口,前端也调用成功;在准备写B接口时,发现和A接口大部分的业务逻辑是一样的,于是把A接口改了改,改成一个公共的方法,可以供A、B同时调用的方法,如果有接口C,也和A、B的情况类似,就可以直接写个简单的接口,调用这个公共方法,调用完这个公共方法,需要写的代码也就很少了。

    那这位小伙伴使用的是解决方法二吗?

    是解决方法二,又不是解决方法二,而是解决方法二升级的解决方法三。

    解决方法三:

    写过前端JS代码的小伙伴都知道,在处理完一个方法时,还可以传递方法名回调另一个方法。没错,这位小伙伴就想到了回调的处理方法,去处理最后百分之五的不同。

    在Java里面可不可以这样写呢?

    答案是可以的,两种写法任你选。

    有那么一个注解:@FunctionalInterface,功能性接口,啥意思呢,先看看它的源码:

    /*
     * <ul>
     * <li> The type is an interface type and not an annotation type, enum, or class.
     * <li> The annotated type satisfies the requirements of a functional interface.
     * </ul>
     *
     * <p>However, the compiler will treat any interface meeting the
     * definition of a functional interface as a functional interface
     * regardless of whether or not a {@code FunctionalInterface}
     * annotation is present on the interface declaration.
     *
     * @jls 4.3.2. The Class Object
     * @jls 9.8 Functional Interfaces
     * @jls 9.4.3 Interface Method Body
     * @since 1.8
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface FunctionalInterface {}
    

    示例代码:

    /**
     * 定义了一个接口,用于传递回调方法
     * @author 程就人生
     * @date 2020年12月21日
     */
    @FunctionalInterface
    public interface Function<T> {
    
        T nextFunction(int i);  
    }
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 测试代码
     * @author 程就人生
     * @date 2020年12月21日
     */
    public class Test {
    
        
        /**
         * A接口,参数省略...
         * @return
         *
         */
        public static Map<String,Object> interfaceA(){
            Map<String, Integer> aa = new HashMap<String,Integer>();
            aa.put("aa", 100);
            //传递各自的业务类,提前把回调方法写好
            Function<Object> callbackFunction=(i)->{
                aa.put("aa", aa.get("aa").intValue() + i);
                System.out.println(i+"aaaa");
                return aa;
            };
            //调用公共方法时,把回调方法当作一个参数进行传递
            return commonFunction(callbackFunction);
        }
        
        /**
         * B接口,参数省略...
         * @return
         *
         */
        public static Map<String,Object> interfaceB(){
            //
            List<String> aa = new ArrayList<String>();
            aa.add("1");
            //传递各自的业务类,提前把回调方法写好
            Function<Object> callbackFunction=(i)->{
                aa.add(i+"");
                System.out.println(i+"bbbbb");
                return aa;
            };
            //调用公共方法时,把回调方法当作一个参数进行传递
            return commonFunction(callbackFunction);
        }
        //公共方法,其他参数已省略
        public static Map<String,Object> commonFunction(Function callbackFunction){
            
            //省略业务逻辑处理代码300行.....
            
            Object obj = callbackFunction.nextFunction(1111);
            
            Map<String,Object> map = new HashMap<String,Object>();
            //返回不一样参数
            map.put("object", obj);     
            return map;
        }
        
        public static void main(String[] argo){
            interfaceA();
            interfaceB();
        }
        
        /**
         * 也可以以内部接口的形式进行定义
         * @author 程就人生
         * @date 2020年12月21日 
         * @param <T>
         */
        /*public interface Function<T> {
    
            T nextFunction(int i);  
        }*/
    }
    

    测试结果:


    在这个demo里,已经把很多业务逻辑省略了,只写了回调函数的使用,回调函数,先定义再使用,既可以使用内部接口,也可以使用@FunctionalInterface注解,这样保证了代码的完整性,是不是很简单呢?

    相关文章

      网友评论

          本文标题:Java里面可以像JS那样写回调方法吗?

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