结束对完整SDLC的空洞模仿
“没有一劳永逸的解决办法,有的只是权衡与取舍”——托马斯·索维尔(Thomas Sowell)
这句话完美地概括了每个软件工程师面临的挑战。问题永远得不到最终的解决。作为工程师,你需要不断权衡,直到找到一个可以接受的折衷方案。一旦部署了解决方案,它的价值就开始下降,然后你又会进入下一个循环。这种衰减如此可预测,以至于你可以用指数衰减模型来描述它。以下是假设软件价值三年内下降20%的衰减曲线图。
软件退化——连续3年每年下降20%
如图所示,该模型预测系统在三年内将失去大约一半(约49%)的价值,这可是一大笔损失啊!还有什么东西会像这样快速贬值?
- 消费电子产品 — 高端的消费电子产品会随着每年推出的新款机型而迅速贬值,因为新机型往往具有更先进的功能。例如,旗舰智能手机每年可能会贬值大约20%至30%,这是由迅速的技术创新和消费者对新机型的需求所推动的。
- 新车 — 新车从购买那一刻起价值就会急剧下降(通常第一年内贬值10%至20%),并且每年继续贬值。平均来说,汽车每年会贬值大约15%至25%,具体取决于品牌、型号和市场条件。大约三年后,许多车的价值会降到原价的一半。
- SaaS产品 — 某些SaaS(软件即服务)工具由于无法满足不断变化的业务需求、行业标准或更好的竞争对手,其感知价值或实际价值会以大约20%的速度下降。例如,过时的软件如果缺乏关键更新或新功能,可能会很快被替代,导致其对企业价值的急剧下降。
所以这些公司为什么还要继续在“过度繁琐的软件开发”上投入大量资金?要回答这个问题,我们先来定义术语。在这里,“过度繁琐的软件开发”指的是围绕软件开发生命周期(SDLC)的工程。这包括:
- 软件开发工作流,例如 GitHub Flow、GitFlow、干枝式开发等。
- 测试环境,如开发环境、测试环境和生产环境
- 测试方法论
- 编码规范
- 静态代码审查
- 软件开发方法论,例如敏捷
所有这些工程活动有一个共同点:它们与速度呈负相关,并因此是为支持规模化而做出的权衡。它们也是企业对一项不断贬值的技术资产的投资,没有这些投资,大规模的软件系统无法进化以适应不断变化的市场需求。这些投资应该尽量减少,以便企业能够实现其目标。然而,今天的常态是开发者们陷入了“cargo cult”(盲目跟风),他们尽可能多地进行投资,导致了我们称之为详尽软件开发(ESD)的局面。
乍一看,ESD(软件开发过程)似乎很谨慎,但我们怎么会不想要明确的工作流程、严格的测试和行业标准的方法呢?问题在于这些所谓的“最佳实践”所带来的意外后果。它们营造了一种进步的假象,同时系统性地拖慢了团队速度,增加了预算,降低了灵活性。更糟糕的是,它们往往过于注重流程,而忽视了成果,使软件工程变成无尽的官僚主义流程,而不是一种交付价值的方式。
大多数被宣传为最佳实践的工程练习——无论是GitFlow还是多阶段的CI/CD流水线——并不是为了优化速度而设计的,而是为了管理规模带来的混乱。讽刺的是,旨在支持增长的流程反而成为创新的障碍。一个工作流程轻量、负担最小的小团队,会持续优于被繁重的测试环境、严格的编码标准和复杂的审批流程拖累的大团队。然而,对工程卓越的狂热仍然存在,往往是以牺牲这些实践本应保持的敏捷性为代价的。
是时候转变我们对工程最佳实践的看法了。与其默认投入最大成本的流程,我们应该专注于最小可行过程——即完成业务成果所需最少的一套实践。团队应定期评估流程是否真正增加了价值,还是仅仅增加了复杂性。如果一个流程无法服务于业务目标或改善用户体验,那么是时候考虑一下它是否真的必要了。
例子移除开发和测试环境。直接部署到生产。
传统的开发和测试环境常常引入不必要的复杂性,减慢开发进度,并带来虚假的安全感。通过直接部署到生产,团队可以简化工作流程,缩短反馈周期,并从一开始就专注于构建坚固的生产级系统。要让这种方法可行,
- 实现功能开关或金丝雀发布,以更安全地在生产环境中测试新功能,而不影响所有用户。
- 采用蓝绿部署或其他类似技术,以最小化部署过程中的停机时间和风险。
- 依赖实时监控和可观测性工具(例如 Datadog、New Relic 或 Prometheus)快速检测和解决异常。
尽可能向左移。使用如Husky这样的pre-commit工具自动处理代码格式、静态代码检查和测试。
往左移意味着将质量保证流程提前到开发周期的早期,以便在问题扩散前及时发现并解决。尽可能自动化这些流程,可以让开发人员专注于编写代码,而不必担心繁琐的手工操作。
如果不是在开发人员层面实现自动化,绝对不要做。
任何依赖人工干预的过程就成了瓶颈和负担。自动化可以节省时间,减少人为错误,保证一致性,并在整个团队中确保标准的一致性。
采用极简主义的方法来处理开发过程。
避免添加那些对交付价值无直接贡献的冗余流程或工具。例如:
- 简化小型且值得信赖团队中的拉取请求审批流程,以消除冗余。
- 通过采用如主干开发等简单流程来简化分支复杂性。
- 只关注能发现实质性问题的测试,而非盲目追求100%的测试覆盖率等任意指标。
投资于监控和应急响应,而不是冗余测试。
在一个软件持续部署的世界里,,实时发现并解决这些问题比试图提前预防所有可能的问题更有用。重点是:
- 建立稳健的监控、日志记录和警报系统,以确保能够尽早发现并解决这些问题。
- 制定清晰且演练充分的事件响应手册,以减少问题发生时的停机时间。
- 测量平均恢复时间(MTTR),而不是试图彻底避免所有错误。
拥抱小而渐进的变化,而不是大型功能。
大型功能会增加复杂性和失败的风险。相反,应该优先交付小而渐进的变化,这些变化更容易测试、部署,如果需要也可以回滚。
让开发人员掌握工具和自主权。
最棒的团队是开发人员能自己做决定并行动,不受繁文缛节约束的团队。
- 为开发人员提供强大且易于使用的自动化工具。
- 减少审批流程,让工程师可以全程对自己的代码负责。
- 建立一种鼓励信任与责任感的文化,鼓励开发人员勇于尝试并从错误中吸取教训。
通过消除不必要的环境,将流程左移(shift left),专注于自动化和简化,团队可以实现更高的速度、更高质量和减少操作开销。不要用这些例子形成另一种“形式主义崇拜”。适合你的组织是在速度和规模之间找到平衡,以带来最大业务价值的权衡。发展你自己的想法并不断改进它。
共同学习,写下你的评论
评论加载中...
作者其他优质文章