【开源之路】温蒂、一次简单的尝试

2021-04-02 10:48:48 浏览数 (3)

.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:30px;margin-bottom:5px}.markdown-body h2{padding-bottom:12px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}

weed的github地址

因为工作中需要进行数据对比,所以经常需要在代码的增删改查操作中嵌入一些对比类。我们都知道开闭原则:对修改关闭,对扩展开放。所以每次修改的时候都需要新增一个类,然后再通知用到了原始类的同事一起同步修改代码。如果方法涉及到的模块少,还可以比较轻松的解决,但是如果用到的地方比较多,那需要协调的地方也会增多。

偷懒是人类文明发展的驱动力

于是,为了解决新增数据对比方法的苦恼,也为了尽量使用少侵入的模式,在工作之余,我也开始思考是不是把放进去的代码再抽出来。思考再三,决定用注解模式解决这个问题,于是乎,就有了weed这一个工具的出现。

当然,现在只是一块不到一千行代码,解决不了绝大多数问题的小工具包。

目前可以公开的情报

  • 1、contrastSourceFundByBean方法专门用来对比两个类对象的信息,类中可以包含任意类 ,但是要记得在类中类加注解。
  • 2、getListupdateOnly方法专门用来对比两个集合的信息,集合中不可包含类,只能是纯基础对象的集合,以后会慢慢更新。
  • 3、judgeArray方法用来比较两个数组之间的信息,数组可以是任意类。
  • 4、注解默认都是可以不加的,需要加的时候是需要用到的时候。
  • 5、这个项目是因为日常给后台人员提供信息对比类的时候想到的,就写出来应该有一点用吧?大家就不用重复造轮子了。
  • 6、weed代表着我第一个十连出了温蒂,第二个十连就出了可莉,第三个十连出了卢姥爷, 其实我挺难受的,香菱60出了可莉,可莉70、武器也70,一整套魔女的时候出了卢姥爷,哎。。。不想要火C了

设计思路

既然决定使用少侵入的模式,那么使用注解的方法就是一个不错的解决方式。

因为网上都有如何使用自定义注解的教程,我这里也就不再班门弄斧,主要展示一下我大概的设计思路。

代码语言:javascript复制
@Target(java.lang.annotation.ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckField {

    /**
     * 字段最小长度
     */
    int minlen() default 0;

    /**
     * 字段最大长度
     */
    int maxlen() default Short.MAX_VALUE;

    /**
     * 字段是否需要校验
     */
    Check check() default Check.unchecks;

    /**
     * 字段名(用于后期获取)
     */
    String name() default "";

    /**
     * 字段类型
     */
    Check type() default Check.basics;

}

校验字段枚举类,这里也主要体现的是一种思路,也是目前提供的解决方案:无论你是基础类型,还是对象、数组,亦或是集合,目前都有办法进行对比,也能拿到所需要的数据。

代码语言:javascript复制
public enum Check {

    /**
     * 检查
     */
    checks,

    /**
     * 不检查
     */
    unchecks,

    /**
     * 对象
     */
    beans,
    /**
     * 数组
     */
    arrays,
    /**
     * 集合
     */
    sets,
    /**
     * 基础数据类型
     */
    basics,
}

最后就是其中的一个方法了,看过我过去文章的同学能够发现,这个方法是在之前的基础上进行了改动,加大了对注解的应用。

代码语言:javascript复制
/**
     * @param oldBean 原始数据
     * @param newBean 新数据
     * @return 根据传入的对象返回变化值
     */
    public static String contrastSourceFundByBean(Object oldBean, Object newBean) {
        StringBuilder str = new StringBuilder();

        Object pojo1 = (Object) oldBean;
        Object pojo2 = (Object) newBean;
        if (!(pojo1.getClass()==pojo2.getClass())){
            return "对象类型不一致";
        }
        try {
            Class clazz = pojo1.getClass();
            Field[] fields = pojo1.getClass().getDeclaredFields();

            Class chkField = CheckField.class;
            int i = 1;
            for (Field field : fields) {
                CheckField cf = field.getAnnotation(chkField);
                if (field.isAnnotationPresent(chkField)) {
                   
                    //获取字段是否填写(不校验,空,非空)
                    if (cf.check().equals(Check.unchecks)&&cf.type().equals(Check.basics)) {
                        continue;
                    }
                    //同意对private字段取值
                    field.setAccessible(true);
                    Object fValue = null;
                    try {
                        fValue = field.get(pojo1);
                    } catch (Exception e) {
                        return "获取字段值异常!";
                    }
                    //获取最大值
                    int max = cf.maxlen();
                    //获取配置最小值
                    int min = cf.minlen();
                    int flength = 0;
                    //为空时判断
                    if (fValue != null) {
                        try {
                            String strVal = fValue.toString();
                            flength = strVal.length();
                        } catch (Exception e) {

                        }
                    }
                    if (max < flength) {
                        return  cf.name()   "长度不能大于"   max   "!";
                    }
                    if (min > flength) {
                        return  cf.name()   "长度不能小于"   min   "!";
                    }
                }
                //获取对象具体信息
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                Method getMethod = pd.getReadMethod();
                    //对象间比较
                    Object o1 = getMethod.invoke(pojo1);
                    Object o2 = getMethod.invoke(pojo2);
                    if (o2 == null) {
                        continue;
                    } else if (o1 == null) {
                        if (filterCheck(cf)) {
                            continue;
                        }
                        String getName = cf.name();
                        str.append(getName).append(":新增值:").append(o2);
                        i  ;
                    } else {
                        if (filterCheck(cf)){
                            String otto = contrastSourceFundByBean(o1, o2);
                            String getName = cf.name();
                            str.append("|").append(getName).append("{").append("[").append(otto).append("]").append("}");
                        }else if(filterChecksets(cf)){
                            String list =getListupdateOnly((List)o1,(List)o2);
                            String getName = cf.name();
                            str.append("|").append(getName).append("{").append("[").append(list).append("]").append("}");
                        }else if(filterCheckarray(cf)){
                            String array =judgeArray(o1,o2);
                            String getName = cf.name();
                            str.append("|").append(getName).append("{").append("[").append(array).append("]").append("}");

                        }else{
                            if (!o1.equals(o2)) {
                                if (filterCheck(cf)) {
                                    continue;
                                }
                                if (i != 1) {
                                    str.append("|");
                                }
                                String getName = cf.name();
                                str.append(getName).append(":旧值:").append(o1).append(",新值:").append(o2);
                                i  ;
                            }
                        }


                    }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str.toString();
    }
    
        /**
     * 对传入的状态进行判断
     * @param cf
     * @return
     */
    private static boolean filterChecksets(CheckField cf){
        return cf.type().equals(Check.sets);
    }

    private static boolean filterCheck(CheckField cf){
        return cf.type().equals(Check.beans);
    }

    private static boolean filterCheckarray(CheckField cf){
        return cf.type().equals(Check.arrays);
    }
}

然后对方法进行一下小小的测试,输出如下:

其余的部分,大家去我的GitHub地址看看吧~,在给大家发一遍 weed的github地址

希望能够一起完善weed~

0 人点赞