【开源之路】温蒂、一次简单的尝试
干点正事吧,巴巴托斯
##V1.01 2020/11/23 温蒂类信息对比处理工具包,目前可以用来对比更新前后的类信息。
weed的github地址
因为工作中需要进行数据对比,所以经常需要在代码的增删改查操作中嵌入一些对比类。我们都知道开闭原则:对修改关闭,对扩展开放。所以每次修改的时候都需要新增一个类,然后再通知用到了原始类的同事一起同步修改代码。如果方法涉及到的模块少,还可以比较轻松的解决,但是如果用到的地方比较多,那需要协调的地方也会增多。
有需要的同学可以加我的公众号,以后的最新的文章第一时间都在里面,也可以找我要思维导图
偷懒是人类文明发展的驱动力
于是,为了解决新增数据对比方法的苦恼,也为了尽量使用少侵入的模式,在工作之余,我也开始思考是不是把放进去的代码再抽出来。思考再三,决定用注解模式解决这个问题,于是乎,就有了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~
我的微信
【开源之路】温蒂、一次简单的尝试相关推荐
- GitHub标星10,000+,Apache项目ShardingSphere的开源之路
[编者按]几天前,当 GitHub 全球产品技术生态总经理 Michael Francisco 谈到中国开发者已经成为 GitHub 上最活跃的群体时,有开发者提出数量之后质量也要跟上.的确,过去十数 ...
- Hadoop之父Doug Cutting:Lucene到Hadoop的开源之路
Hadoop之父Doug Cutting:Lucene到Hadoop的开源之路 Doug Cutting,凭借自己对工作的热情和脚踏实地的态度,开创了Lucene和Nutch两个成功的开源搜索引擎项目 ...
- GitHub 标星 10,000+,Apache 顶级项目 ShardingSphere 的开源之路
[CSDN 编者按]几天前,当 GitHub 全球产品技术生态总经理 Michael Francisco 谈到中国开发者已经成为 GitHub 上最活跃的群体时,有开发者提出数量之后质量也要跟上.的确 ...
- Windows 10“源码泄露“让我想起微软“开源之路”
写这篇文章的重点不在于Windows 10"源码泄露"后给微软带来什么损失,又或给黑客带来什么可趁之机(类似文章太多,我就不凑热闹了).因为各种猜测意淫对读者毫无价值,写此类文章无 ...
- 7月10日云栖精选夜读丨ApsaraCache开源之路,阿里云Redis团队LC3全球顶级开源峰会获CRUG开源社区最具影响力奖...
近日由The Linux Foundation主办的全球开源盛会LinuxCon + ContainerCon + CloudOpen(LC3)中国在北京国家会议中心举行,阿里云Redis团队也受邀参 ...
- 【我的区块链之路】- Hyperledger fabric的简单入门(四)链码的编写及调试
[我的区块链之路]- Hyperledger fabric的简单入门(四)链码的编写及调试 之前的文章中我们有讲过了fabric的一些核心的配置文件的选项说明,讲过fabric 的网络启动 ...
- 安装开源在线教育平台edX的一个简单方法
开放式在线教育平台edX在今年六月份开源,当时按着Google Group中的方法"Clean install on Ubuntu Server 12.04"在一台全新的VPS上安 ...
- 深入浅出Docker(三):Docker开源之路
背景 Docker从一开始的概念阶段就致力于使用开源驱动的方式来发展,它的成功缘于国外成熟的开源文化氛围,以及可借鉴的社区运营经验.通过本文详细的介绍,让大家可以全面了解一个项目亦或者一项技术是如何通 ...
- SQL、NoSQL、NewSQL,论开源之路谁主沉浮
天下大势,分久必合,合久必分,没有什么是永恒的.在SQL的发展过程中,占据数据库市场绝大部分的SQL.NoSQL.NewSQL,目前也呈现出融合的趋势.也许开源的未来之路只有一条,但在当下,于企业而言 ...
最新文章
- AngularJS API之isXXX()
- Getting started with Apache Camel--转载
- gba徽章机器人_徽章战士GBA攻略
- Android报“android.content.res.Resources$NotFoundException: String resource ID #0x2”错误
- IT管理人才必备的十大能力(转)
- Python爬虫教程:requests模拟登陆github
- 没有黑色版本?AirPods 2广告泄露:外型无变化
- 字节AI LAB NLP算法二面凉+被捞后通过
- ios-团购代码的重构
- android NDK 详解
- 腾讯视频弹幕爬取----------之亲爱的,热爱的
- 3DMAx:能导入导出的文件格式
- H5页面唤起微信等app
- Windows用户远程访问内网共享文件(免费内网穿透)
- 怎样把视频中的一小段制作成 GIF动图
- 【Python爬虫】第三课 网页爬取
- linux 64位数据库下载地址,Linux 7 平台 64位 DM8(8.1.0.147) 安装文件下载地址
- SQL SERVER中的汉字转拼音-实现根据拼音搜索汉字
- Google工作10年的职场感悟
- Cesium地下管线信息系统(视频)