最近游戏开发业务少了,我就开启了重构运营系统的行动了。先说一下背景,运营系统是个很多人接手过的项目,代码风格迥异,因为团队没有review机制,以前后台的同学都是怎么方便怎么来,完成任务就万事大吉了。
因为公司的业务,这里不会贴上代码,大致描述一下在代码结构上主要存在的问题:
- 代码为了复用而复用,没有语义,没有遵循单一责任原则。
- 重复性代码太多,相同逻辑的代码直接copy修改。业务层接口粒度太大,有很多可以进行垂直拆分的公共代码。
- 重复的、有更好替代的工具类/公共类太多。见过最经典的一个例子:一个IO流异常处理的代码片段直接放在一个工具类进行复用,并且只有两三处调用。
- 上帝类。一个公共类想做的事情太多就意味着引入了过多的依赖,修改依赖的代码很容易影响已有的业务。
按照上面的问题,反推重构方案:
- 将看到的没有语义或不规范的api先进行inline处理,在按照实际情况判定是否进一步提取公共api。
- 将业务层显眼的公共代码片段按语义进行提取,遵循单一责任原则,对业务进行垂直划分。
- 将可以用开源工具类(guava、common-utils、spring-utils)替代的直接删除,用开源工具类替代,将业务无关并且简单实现已经没有调用的接口、工具类移除。
- 将上帝类水平拆分,按照domain水平拆分到应有的位置,不能做拆分和过多依赖的服务,尝试将服务下沉做公共服务。
因为只是代码结构变化,并没有修改业务的实现,通过现代的IDE是可以直接进行操作的,但是需要逐步review和按模块进行version control。
运营系统指责单一,业务量不大并且按照实际的业务情况不需要做服务拆分和集群,资源占用太大的调度可以单独拆分出来,开多个实例处理。这个小型系统的形状其实跟游戏后端一样,在宏观上是十分内聚的。(目前研发的游戏也是单一进程的)但从微观上讲,良好组织的代码应该像组件化、服务化的服务一样,对内聚合、对外松散。从宏观上看,大型服务架构系统其实也应该这样。每个服务就像游戏开发的组件、小型系统的模块一样,是独立自治的。只不过业务的调度不会在一个进程、单机内,可能是多点的、集群的甚至多地的。得益于中间件技术,将这些服务按实际的商用业务串联起来。在不同的角度,可以说它们按结构来看是极度松散的,也可以说他们高度内聚的。按宏观上来看,后端开发其实是相似的,只是面对实际要解决的问题各有各的不同,按实际情况选择最优解罢了。本人拙见,贻笑大方。