一个中大型的系统因为业务快速迭代,某些模块不断由于项目的排期,引入临时方案,而临时方案最后又变成了最终方案。
这种技术债务不断积累,致使模块逐步变得僵化,对业务的支撑只能依靠研发团队不断加班,在原有的系统上打补丁来支持,维护成本很高,扩展性不强。
这个过程不断持续,整个系统处处都是坑,到最后,只有用一个新的系统来替代,把老系统下线。
这种粗粒度的重构,一般都涉及比较广的业务范畴,若是考虑不全面,实施很差,会对整个系统形成灾难性的后果。
这两年在部门进行了几回核心子系统的重构,有一些我的理解的重构原则,简单总结一下。
首先,是对遗留系统的功能作减法,从业务层面选择最基础和最核心的功能优先完成。
一个软件系统,20%的功能就能够知足业务方80%的功能,选择这20%的功能首先进行重构,能够在较短的时间构建一个可使用的版本上线;等新系统上线以后,按照重要程度从剩下的80%的功能点选择一部分迭代开发,对于原来一些不经常使用的辅助性功能能够直接丢弃,避免没必要要的复杂度。
商业系统一般业务流程比较重,而且和整个组织架构的角色权限结合在一块儿,在重构的过程当中,也能够和业务方一块儿对流程进行精简,进一步下降系统的复杂度。
此外,若是核心领域模型存在多个版本,在重构的时候要在系统内部完成统一,从根上解决基础数据结构多样性带来的业务复杂性。
好比对于电商系统,商品是最基础的领域模型,若是系统内部存在多个版本,业务层须要根据不一样的版本进行不一样的处理,而这些处理的业务逻辑,可能散落在系统的各个角落,业务代码copy&paste,缺乏统一的处理模式,if-else满天飞。
对于这种状况,先要从逻辑层面设计统一的商品模型,另外从物理层面设计数据迁移方案,保证新系统再也不出现这种状况。
其次,新系统对遗留系统的替代,是一个相似灰度发布的过程,要设计可行的并行方案,从而下降由于新系统不稳定对业务带来的影响。
新系统是为了解决遗留系统扩展性和可维护性的问题,从总体架构设计角度进行的优化升级,即便是通过充分测试也没法保证上线以后不会出现问题,尤为是在开发节奏快、项目排期紧的状况下。
若是新系统上线后立刻下线老系统,由于bug、性能、交互设计等等致使用户满意度降低,这将给新系统的开发团队带来很是大的压力,一方面要快速处理新系统的问题,另一方面还要开发遗留系统的功能点,这对系统的稳定性带来极大的风险。
规避这种风险的方法就是在项目开始的时候就思考如何引入小流量的方案,逐步引导用户迁移到新系统。
第三,要充分考虑对周边依赖系统的影响,在服务层进行向后兼容设计。
服务层是由一系列的API构成,在重构的时候,一般的思路是设计新版本的API集合,根据新系统的领域模型对输入&输出进行从新设计,同时保留原来的API,这种方案适用于调用方比较少的状况。
若是调用方不少,每一个调用方都须要配合进行重构,上面的方法,不论是从项目推进仍是风险控制都存在问题。
这种状况,能够考虑引入一个服务分发层,保证API接口不变的状况,根据API调用的上下文,把请求分发给遗留系统和新系统分别处理;分发层聚合调用结果,从而达到对调用方透明的目的。
当遗留系统彻底下线以后,在新系统里去掉分发层,完成整个服务层的迁移。
新系统重构完成以后,为了不通过一段时间的演进,蜕化为另一个遗留系统,须要在功能迭代过程,处理好质量要求和项目进度的矛盾,这是另一个值得深刻讨论的话题。