通往“工程效率目标”的道路上,有13大凶兆出没……
在讨论软件研发工程效率之前,需要明确工程效率的目标到底是什么。
一提到工程效率的目标,很多人的第一反应就是“要快”。
但什么要快?是研发人员要更快地忙碌吗?如果价值流动到用户手中很慢,研发人员忙得再快,也是没有用的。
不管是工程效率的目标,还是敏捷、精益、DevOps的目标,如果放到软件开发的领域,那么目标都只有一个。
工程效率的目标,就是让用户能及时在生产环境,持续稳定地享受软件所提供的良好服务。
这个目标的定义,其实涉及了工程效率的四个维度。
图1. 工程效率的目标与四维度
工程效率的目标,就是让用户能及时(流速快)在生产环境,持续稳定地(稳态久)享受(价值准)软件所提供的良好服务(质量好)。
这四个维度,可以按照重要性进行排序:
其中,稳态久,指后面3个维度“价值准”、“流速快”和“质量好”,都要能持续地保持,即能保持收益稳态。之所以排名第一,是因为其所涉及的“凶兆1:用线性思维解决复杂系统问题”,经常被大家忽视,导致开发团队难以保持后面3个维度的收益稳态。
流速快,指价值向用户流动的速度快,而不是指某个员工或某个部门完成工作的速度快。因为如果价值在两个部门间发生了等待,即使每个部门工作得再快,价值流向用户的速度还是变慢了。
在通往工程效率目标的路上,潜伏着13大凶兆,阻碍工程效率的达成。
图2. 阻碍工程效率的13大凶兆
这13大凶兆,按工程效率的四维度,可分为4类。
为何软件开发过程本身,就是一个复杂系统?
我们身边有很多复杂系统的实例,比如全球气候、人脑和电网等等。
复杂系统具有以下特点:
想想在软件开发过程中,光涉及到的人员、设备、数据、过程、环境就多得不计其数,更别提它们之间的相互关系的数量了。
有人说能否将复杂系统,简化为线性的简单系统?这样就不必应对复杂系统了。
遗憾的是,这样做,短期可行,但长期不可行。
Frederick Brooks于1986年在论文No Silver Bullet中,将复杂性粗略地分为两类——偶然复杂性和本质复杂性。
软件开发的资源,总是有限的。所以妥协总是要做出的。一旦做出妥协,就会形成次优代码。而次优代码不断积攒,总会到达一个令人难以理解的状态。这样就出现了偶然复杂性。
软件的功能越丰富,复杂度越高,就增大了本质复杂性。W. Ross Ashby于1958年所发表的论文Requisite Variety and Its Implications for the Control of Complex Systems中解释了“必要多样性法则”。简而言之,对于能够完全控制系统B的系统A,必须至少与系统B一样复杂。
简言之,只要资源有限,且不断增加新需求,那么偶然复杂性和本质复杂性就必然随着时间推移,不断增大。这样,就无法实现将复杂系统,简化为线性的简单系统。
应对复杂系统的方法有哪些?有下面两种。
第一,是可视化安全边界。
Jens Rasmussen于1997年在论文Risk Management in a Dynamic Society所提出的“动态安全模型”。
图3. 动态安全模型
可以想象,图中的小人腰上拴着3根橡皮筋,每一根都绑到相应的一个方块上。
因为人对于“经济性”和“工作量一般都有直觉,比如不会随意浪费,每天至少有几小时的睡眠和休息,所以这两根皮筋一般不会绷断。但由于“安全性”很少能被可视化出来,所以员工经常会让系统在线上出现故障,从而把“安全性”这根橡皮筋绷断。
所以,应对复杂性,可以把安全边界可视化出来,让员工自觉地远离漏洞,减少故障的风险。
第二,是改善可逆性。
Trento大学经济学系主任Enrico Zaninotto教授于2002年在一次演讲中所提出的“复杂性的经济支柱模型”。
图4. 复杂性的经济支柱模型
在复杂系统中,如果缺乏“可逆性”,即使能在“状态”、“关系”、“环境”上取得优势,那么所获得得收益也是暂时的。比如上个世纪福特的T型车,通过标准化零件,车身只有黑色,来减少”状态。通过标准化工人在流水线上动作,简化人与流水线的关系。通过打赢了与ALAM美国特许汽车制造商协会的官司,创造了设计创新车型,不再支付高额许可费的环境,从而让汽车首次进入寻常百姓家。但面对之后丰田的能实现“可逆性”的精益制造,福特却败下阵来。
在应对复杂系统时,可以使用上述两种方法,来让应对的过程更安全和更灵活。
下面会从应对剩下12个凶兆的技术中,选取一些技术,来讨论它们如何能体现出“可视化安全边界”和“改善可逆性”。这能帮助我们更好地理解,一些熟知的技术,是如何能通过这两种方法,应对复杂系统的。
分析用户问题的技术有哪些?
用户画像,通过描述用户痛点,可视化了安全边界。
分析用户问题的工具有何推荐?
解决“找不到业务和测试人员”的技术有哪些?
带有验收条件的用户故事,既通过验收条件可视化了边界,又通过用户故事本身都是需求纵向拆分的小批量,来改善可逆性。
拆分大需求的技术有哪些?
用户故事拆分,通过小粒度的需求纵向拆分,能加快价值流速,尽早获取用户反馈,改善了可逆性。
应对“大批量上线”的技术有哪些?
特性开关,通过调整开关来决定特性是否能够发布,来改善可逆性。
应对“线上故障修复过程不规范且耗时长”的技术有哪些?
基础设施即代码,当抢修故障时,能通过代码从零开始构建整个健康状态的基础设施,从而改善可逆性。
“从本质上讲,长寿命分支与将所有变更都不断集成到源代码库背道而驰。”——技术雷达2020年5月
应对“长寿命Gitflow分支”的技术有哪些?
主干式开发,通过频繁小批地解决合并到主干上的代码提交的冲突,来可视化安全边界,并改善可逆性。
应对“大批量代码提交”的技术有哪些?
图5. 7步提交法
7步提交法,既通过本地和流水线代码构建可视化安全边界,又通过失败提交回退改善了可逆性。
应对“线上故障频发”的技术
验尸报告,能通过记录线上事故的整个过程和所发现的漏洞,可视化安全边界。
应对“烂代码”的技术有哪些?
应对“烂代码”的工具有何推荐?
技术债管理,通过静态代码扫描工具,发现漏洞,可视化安全边界
快速发现代码集成问题的技术有哪些?
快速发现代码集成问题的工具有何推荐?
“Jenkins 2.0虽然引入了“流水线即代码”,但却继续使用插件对流水线进行建模。且未能将核心Jenkins产品更改为直接对流水线进行建模。 根据我们的经验,将部署流水线视作一等公民的构建工具才更好用。”——技术雷达2016年11月
做好Code Review的技术有哪些?
尽早、频繁、小批的Code Review,既能发现代码漏洞,可视化安全边界,又能及时修复漏洞,改善可逆性。
应对“单人开发”的技术有哪些?
结对编程,既能通过随时提出编程反馈,实现可视化安全边界,又能通过修复代码缺陷,改善可逆性。
衡量工程效率的指标,按工程效率的四维度,也可分为4类,共16个。
这16个指标,每个都属的维度,代表了这个指标所衡量的价值。
每个指标,都以“渐多”、“渐好”或“渐快”结尾,表示指标的绝对值没有意义,而与自己团队之前的指标相比,才有意义。
这16个指标,并不是一成不变的,需要根据团队的实际情况,进行取舍,或增加新指标。
图6. 如何衡量工程效率
工程效率的目标,就是让用户能及时在生产环境,持续稳定地享受软件所提供的良好服务。
在通往工程效率目标的道路上,按稳态久、价值准、流速快、质量好这4个维度分类,潜伏着13大凶兆。如果在团队开发工作中,看到了这些凶兆,就要警惕。
可以参考16个度量指标,来度量工程效率的变化趋势,以便达到工程效率的目标,并持续稳定地保持该目标的达成状态。