我有各种各样的Java对象集,其中一些是由JAXB工具生成的pojo,其中一些是域类等。在大型应用程序中,我需要从一组对象中获取数据,并将其放入具有不同功能的另一组对象中。
有多种方法可以做到这一点:对象映射框架是一个明显的选择。然而,大多数具有坚实代码基础和社区的框架都使用反射。(例如推土机)我一直在使用适配器的组合,它采用pojos和更复杂的java类来访问模式,这样访问者在适配器上走过一组对象,并在此过程中创建另一组对象(对象通常具有父/子/树类型的引用),特别是当使用引用传递而不是创建新的字符串等时,这应该是最快的方法。
你能想到其他方法吗?对内存中的字节数组进行某种序列化,然后可能是反序列化?就性能而言,它能打败基于访问者的副本吗?我对Dozer等基于反射的方法是否不公平?这是应用程序中的一个关键操作,因此任何改进都可能显著提高整体性能。
访问者模式应该非常接近性能最佳。由于任何类型的广义映射的开销,任何涉及序列化的事情都会变得更糟。
我不是特别熟悉dozer——但是如果反射本质上是用来自动化你手工编写的代码,那么它就不一定是一个巨大的打击;也就是说,如果它一次生成一个类(或等价的逻辑树)来定义复制操作,然后重复运行这个操作。反射成本被平摊在大量的操作上,变得可以忽略不计。
在一天结束时,您确实需要一个基准和最低需求。
如果您已经满足了复制的最低时间要求,您可以避免更改任何代码并继续前进。如果你不这样做,当你达到最低要求时,你可以停止。
对于每一个"快"的方法,总是有一些其他的方法可能更快一点。快速陈述最低需求告诉您是否需要快速(或者您只是过早地优化),以及何时停止投入资源以使其更快。
制作一个好的java基准并不太难,但是在尝试之前一定要仔细阅读它(因为制作一个糟糕的基准非常容易)。
Facade模式的适配器将是一个好主意。你复制的数据越少越好。另外,让你的数据不可变也是一个好主意,这样你就可以在将来避免并发问题。
我将远离内存序列化,特别是在改变格式时。
反射也是如此。如果您有很多对象,并且不想手工编写适配器,那么最好使用模型驱动方法,并将生成的适配器作为构建过程的一部分。
如果您关心的只是传输数据,而不是实际创建来自两个不同类的字段的复合对象,那么我建议使用facade。facade将把您分派到几个不同的对象,并从这两个对象中返回一个数据传输对象(DTO)。
http://en.wikipedia.org/wiki/Facade_pattern有些人会争辩说,既然你不是在执行功能,而是返回一个复合,那么这将被称为复合或包装器或适配器,但无论如何,我仍然会采用这种方法。
我通常从这里开始:
http://www.javacamp.org/designPattern/