重复造轮子,意思是说,一个项目本身存在开源组件,但开发团队还是选择重新手写一套组件库或框架的情况,这在软件业界比比皆是。
下面说下游戏项目里重复造轮子的几点原因。
一,精简化
一般开源项目为了适应多场景多业务,底层不可避免的需要深度抽象。在更好地支撑上层业务的多样性的同事,也牺牲了开源项目本身的敏捷性和灵活度。
例如Hibernate很强大,但很复杂,其提供的绝大部分功能在游戏里都没有用武之地。游戏项目对于数据库的操作有以下几点特点:
- 绝大部分是增加、查询、修改
- 很少进行删除操作
- 极少进行联表查询
针对游戏项目,我们完全有理由重新造一个最小化的orm工具库。
二,适配性
JPA接口虽然提供了针对数据库列数据与对象的转化
package javax.persistence;public interface AttributeConverter<X, Y> {// 对象属性转为数据库列数据Y convertToDatabaseColumn(X var1);// 数据库列数据转为对象属性X convertToEntityAttribute(Y var1);
}
但遇到游戏项目经常使用到的json工具库(主要是jackson)便显得有些捉襟见肘。原因是我们经常在业务代码用jackson来序列化一些泛型数据容器,在将字符串转为实体属性的时候,如果没有实体属性本身的class信息,是无法反序列化成功的。
针对以上问题,我们重复造轮子的时候,就需要对orm工具的接口做适当适配
package jforgame.orm.converter;public interface AttributeConverter<X, Y> {// 对象属性转为数据库列数据 Y convertToDatabaseColumn(X attribute);// 数据库列数据转为对象属性, clazz参数是新增的X convertToEntityAttribute(Class<X> clazz, Y dbData);}
三,拓展化
目前的orm工具库,对实体的修改都是整体修改。也就是说,假设数据库表有50个字段,业务代码只修改了其中一个字段,orm在保存的时候,仍然是50个字段整体修改。在我们重复造轮子的时候,可以在自己的工具里加入修改单表指定字段的接口。
更进一步思考,我们可以在实体属性发生变化的时候,程序自动监听到属性发生变更,然后定时把收集到的变动字段持久化到数据库。这种思路可以参考下这篇文章。Java实现数据劫持——监听属性变更