关于Java属性映射正确姿势的探讨
来源:10-9 出现缓存雪崩该怎么办?如何避免?
LBruce
2021-06-23
背景
日常开发中为了更容易维护,易于拓展等原因会使用各种分层领域模型(BO,VO,DTO,DO…),这就会存在一个非常棘手的问题即:编写不同的模型之间相互转换的代码非常麻烦…
常见的 Java 属性映射方式有以下几种:
Getter/Setter 方式
org.apache.commons.beanutils.BeanUtils
org.springframework.beans.BeanUtils
org.dozer.Mapper
mapstruct
不同方式之间的比较:
除了自己写get/set方法外,其余的方式都可以归属于利用属性转换工具做转换。
属性转换工具的优势:
用起来方便,往往一行行代码就实现多属性的转换,而且属性不对应可以通过注解或者修改配置方式自动适配,功能非常强大。
属性转换工具的缺点:
- 对象映射的时候,如果属性不完全一致则容易出错
- 有些转换工具,可能会出现意想不到的 BUG
- 基于反射的映射工具实现映射,性能会稍差一点,比不上get/set
- mapstruct是用操作字节码的方式,编译时会自动生成转换工具的实现类实现转换,性能理论上比反射快,但是一样存在第5点的问题。
- 基于反射和字节码增强技术的映射工具实现的映射,对一个类属性的修改不容易感知到对其它转换类的影响。这一点尤其致命!
一个 UserDO 如果属性超多,转换到 UserDTO 再被转换成 UserVO 。如果你修改 UserDTO 的一个属性命名,其它类待映射的类新增的对应属性有一个字母写错了,编译期间不容易发现问题,造成 BUG。
如果使用原始的 Getter/Setter 方式转换,修改了 UserDO 的属性,那么转换代码就会报错,编译都不通过,在编译阶段就能提醒我们修改属性所带来的错误影响。
手写get/set的优势:
性能优于反射,并且更重要的是对一个类属性的修改非常容易感知得到,如果转换代码没跟上所做变动,那么在编译期间就会报错,避免Bug产生。
手写get/set缺点:
繁琐,不过可以借助一些IDEA插件,比如GenerateAllSetter 或者 GenerateO2O,稍微减少一些工作量。
我的属性映射姿势
为了避免转换函数散落到多个业务类中,在项目中单独新建一个convert包,在convert包下实现一个个convert工具类,负责实现层与层之间对象的转换,然后安装上IDEA插件GenerateAllSetter,更快地完成get/set~
一哥对此有什么见解?谢谢一哥解答。
1回答
-
同学你好:
首先感谢你的分享,我这里提出两点建议:
(1)这类代码确实是非常麻烦而且都是重复性的,没有任何技术含量的;所以,我建议越简单的实现越好(get、set 就挺好,而且一定不会出错)
(2)我们更多的应该把精力放在业务逻辑上,这些对象之间的转换,方法实现太多,任意挑选一种你习惯的和喜欢的就可以了,不需要考虑太多 『漂亮』的实现,对你的技术提升其实没有太多的帮助!
我是勤一,欢迎随时找我!
20
相似问题