不当的架构重构让屠龙少年成了龙

      在巨大的交付压力下,往往面临架构严重腐化的问题(巨大交付压力下,如果开发团队没有足够的定力和架构能力,往往会选择dirty&quick的方式大批量交付需求,对架构的重构/守护往往会被最先放弃,从而加速架构快速腐化)。

       随着功能增加,越来越多的腐化架构要素被新功能包裹,彼此纠缠耦合穿插交错越来越深,就像砂砾被贝壳包住生成珍珠一样,后续很难再轻易挖出来。

       造成系统维护难度越来越大,发散式变化和散弹式修改比比皆是,代码很难读懂甚至很多功能都难以合入,交付速度也越来越慢,这种情况下架构重构就成为必选项,但是架构重构工作量巨大,不可能一蹴而就,加之遗留系统往往没有足够有效自动化测试用例保护,大规模架构重构又会直接影响系统质量,加大交付困难。

        交付困难引发架构重构,架构重构又造成更大的交付困难,这就陷入鸡生蛋还是蛋生鸡的问题。

        这种困境下,很多团队leader和架构师由于经验不足,往往拍脑袋采用简单粗暴的休克疗法,即两套系统的打法:

1、老系统面对交付,继续保留相应规模的开发人力,大面积合入新功能和bug。

2、同时招聘组织一批新的人马,同步开发全功能的新系统,功能对齐老系统的某一个大版本v后。然后再合入老版本v后续的功能和bug。

        看起来是不是很完美呢?其实有很多问题:

新系统可能踩二遍坑

        大规模重构一定要尽量使用老版本的大多数基干人力,这样老版本的隐性业务规则、致命的实现约束等无数bug换来的经验才能平移继承过来;像这样另起一套人马蛮干一般都还得吃二茬苦踩二遍坑。

新系统架构可能再次腐化

        大规模重构时间一般都比较长,新系统重构时老系统还在加速前进,新老功能对齐是个漫长的过程,新系统很难快速上线,甚至在漫长的对齐老系统功能中,如果没有架构守护,加之新系统一般都会补充大量缺乏经验的新员工甚至毕业生,新系统架构很快又会腐化,屠龙少年变成了龙,用来解决问题的方案又变成了新的问题是件很尴尬的事情。

巨大人力成本

        大规模的新老系统同时开发和测试、运维要耗费大量人力,新系统会脉冲式的耗费大量预算拼命招人。

        对齐老系统功能后,老系统新功能和bug新老系统都要两边合入。机械的、重复的大量的编码、验证等工作造成巨大的人力浪费和士气低落,部门和项目人数居高不下,加班加点昏天黑地,人员稳定性也会大幅下降。

        且新系统一旦上线,老系统的维护人力会持续萎缩进而大批量释放,人力大规模脉冲波动也会给公司造成大量人力成本。

        因此,这种困境应对的关键是必须找到一种能够随时停止的重构方式,能够在持续交付的同时逐步进行架构微服务演进(见下图)。

图片

一、对于存量功能,这里我们提出一种随时可以停止的架构微重构的方式:

1、建设并存系统

        开发一套clean architecture的系统,和遗留大泥球系统并存,新系统要求:

a、包含清晰的领域模型(充分满足最小知识原则)

b、合理的依赖关系(单向依赖,缩小依赖范围,向稳定的方向依赖等)

c、功能可相对独立的功能,逐步扩充

开发脚手架

        很多很牛逼的建筑都是看不到脚手架的,其实是建筑师充分利用了脚手架功能后,把脚手架拆除了。看不到并不等同于不存在。

a、入口转发层

        重构好的功能路由到新提供,遗留功能还是透传到老系统。

b、数据结构适配层

        老系统一般都是结构混乱,数据结构散乱和交叉;而新系统一般数据结构都比较内聚且封装隐藏较好,老系统和新系统的交互需要进行接口和数据结构的转换,提供一个适配层来转换接口和数据结构。

功能逐步迁移

a、新增功能优先在新系统中实现

b、相对独立功能优先移植到新系统

c、核心数据结构和功能优先在新系统中实现,实现过程采用蚂蚁搬家的方式进行,新系统重构可以根据交付压力大小随时停止。

拆除脚手架

        功能移植完成后,老系统废弃掉,拆除脚手架,得到一套clean architecture的架构。

案例

        笔者曾经主导使用这种脚手架+架构微服务的框架重构过很多系统,都获得过良好的效果,比如:

a、多个web前端页面中anglar向vue演化

b、多个web后端java spring切换到nodejs

c、单板嵌入式开发中c切换到erlang

d、大型服务进程c切换到c++

        这些系统规模普遍角度,重构过程中,都是新老共存,一套人马一种交付,保证正常交付的情况下逐步过渡,持续寸进,做靠谱的人干靠谱的事。

        对这些案例有兴趣的可以跟我进一步交流。

二、对于增量功能的架构腐化,必须先止血

止血就是要建立架构守护组织和流程

事前对架构腐化的识别

        在需求分析和重大bug修复的时候,提前对是否影响架构进行识别和标记,并指导开发落地。

事后对架构腐化进行拦截

        通过SA(系统架构师)的架构验证、架构checker扫描、架构度量系统CI拦截等三道关口,发现新的架构腐化需要及时标明技术债并择机重构,从而形成有效的架构腐化防护手段。

三、架构能力建设

        有了微重构的框架和架构防护机制,还需架构设计的能力提升才能匹配,否则就是小马拉大车,跑不动。

系统级架构设计

        从业务架构到逻辑架构、系统架构、数据架构、部署架构、运行架构等,我们首推DDD、MBSE、DCI、分布式架构设计、微服务架构设计、云原生架构设计等方法。

模块级架构

        首推设计模式以及背后的设计原则,做好依赖管理,遵循好最小知识原则。

代码级设计

        clean code、重构(消除坏味道),做好知识的封装隐藏,充分运用好最小知识原则

        就像练武术一样,架构重构和守护方法相当于招式,架构能力相当于功力,只有功力深厚,招式才能发挥出最大威力。

        综上,对于存量架构的重构一般都是伴随着交付压力的,必须打造一种可以随时停止的架构微重构框架;对于增量功能需要逐步建设架构守护的组织、流程、方法,并形成长效机制。

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/213243.html

(0)
联系我们
联系我们
分享本页
返回顶部