【开源之路】温蒂、一次简单的尝试
干点正事吧,巴巴托斯
##V1.01 2020/11/23 温蒂类信息对比处理工具包,目前可以用来对比更新前后的类信息。
因为工作中需要进行数据对比,所以经常需要在代码的增删改查操作中嵌入一些对比类。我们都知道开闭原则:对修改关闭,对扩展开放。所以每次修改的时候都需要新增一个类,然后再通知用到了原始类的同事一起同步修改代码。如果方法涉及到的模块少,还可以比较轻松的解决,但是如果用到的地方比较多,那需要协调的地方也会增多。
偷懒是人类文明发展的驱动力
于是,为了解决新增数据对比方法的苦恼,也为了尽量使用少侵入的模式,在工作之余,我也开始思考是不是把放进去的代码再抽出来。思考再三,决定用注解模式解决这个问题,于是乎,就有了weed这一个工具的出现。
当然,现在只是一块不到一千行代码,解决不了绝大多数问题的小工具包。
目前可以公开的情报
-
1、contrastSourceFundByBean方法专门用来对比两个类对象的信息,类中可以包含任意类 ,但是要记得在类中类加注解。
-
2、getListupdateOnly方法专门用来对比两个集合的信息,集合中不可包含类,只能是纯基础对象的集合,以后会慢慢更新。
-
3、judgeArray方法用来比较两个数组之间的信息,数组可以是任意类。
-
4、注解默认都是可以不加的,需要加的时候是需要用到的时候。
-
5、这个项目是因为日常给后台人员提供信息对比类的时候想到的,就写出来应该有一点用吧?大家就不用重复造轮子了。
-
6、weed代表着我第一个十连出了温蒂,第二个十连就出了可莉,第三个十连出了卢姥爷, 其实我挺难受的,香菱60出了可莉,可莉70、武器也70,一整套魔女的时候出了卢姥爷,哎。。。不想要火C了
设计思路
既然决定使用少侵入的模式,那么使用注解的方法就是一个不错的解决方式。
因为网上都有如何使用自定义注解的教程,我这里也就不再班门弄斧,主要展示一下我大概的设计思路。
@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;
}
校验字段枚举类,这里也主要体现的是一种思路,也是目前提供的解决方案:无论你是基础类型,还是对象、数组,亦或是集合,目前都有办法进行对比,也能拿到所需要的数据。
public enum Check {
/**
* 检查
*/
checks,
/**
* 不检查
*/
unchecks,
/**
* 对象
*/
beans,
/**
* 数组
*/
arrays,
/**
* 集合
*/
sets,
/**
* 基础数据类型
*/
basics,
}
最后就是其中的一个方法了,看过我过去文章的同学能够发现,这个方法是在之前的基础上进行了改动,加大了对注解的应用。
/**
* @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<CheckField> 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~
微信公众号,有兴趣的小伙伴来关注一下吧~我最新的内容都会在这里发布