运营期游戏项目重构实践复盘
已上线的功能,谨慎确认其是否需要重构
通常目前游戏项目很少实践自测试代码,并且集成测试大量依赖手工测试,在这种情况下,开发人员重构带来的风险往往大于收益。
因为如果这个功能已经上线,那么重构之后被破坏,可能会引起玩家大量的投诉。
比较好的做法是准确地分离出新内容与旧内容的边界,让新内容与旧内容完全隔离。
遇到冗余代码,难道就故意冗余?
经常想重构是因为新开发的系统与旧系统有很多共用的代码。如果发现新系统可以直接用旧系统的代码,这时候可以将旧系统的一些功能抽离到一个公共的新模块,由新旧系统共同引入。
这里必须小心,你不能改变旧系统功能的逻辑。因此只做一些安全的操作,例如和旧系统完全一致的类、数据格式,以及无副作用的函数。
什么时候不应该重构?
之前我遇到过的一个需求,一个旧的玩法需要用新的一套UI,但其逻辑完全不变。
而我看到这个玩法系统的代码将数据和表现耦合在一块,因此后面对旧玩法的数据、表现层代码进行了彻底的重构。重构之后,原先旧的玩法进行了大量的测试,耗费了不少时间和精力。
事后复盘,其实更优的做法应该是:在旧代码的基础上,将引用UI控件路径的代码抽离成一个单独的struct,
为什么这样做更优?因为struct不带行为,只存储数据,新旧UI用存储了各自UI空间引用路径的struct代替,并被原先的旧系统代码使用。这样做到了
- 完全不动到原先玩法的逻辑,无需回归测试,开发效率是最高的。
- 满足了新的需求的目的
- 代码兼容旧的UI。
所以这里的问题应该是重构的边界问题,这个需求需要重构的部分仅仅是旧代码对UI引用的部分,而不是整个旧系统。过度重构带来的问题就是影响到旧系统的代码,带来系统被破坏的风险以及进度上的延误。
已上线代码的类给予了不想要的数据和行为该怎么做?
如果新开发的内容继承自一个旧的类,而此时不需要这个类附带的某些数据和行为时,这个时候该怎么做?
比较好的做法应该是抽离出一个新的基类,新的基类包含新类想要的数据和行为。
参考资料
- 《重构:改善既有代码的设计(第2版) 》