为什么产品稳定性在 Scrum 中如此重要?
Scrum 是一种经验主义方法,通过交付“产品增量”来为客户持续创造价值。这种方法使得 Scrum 团队能够频繁快速地验证他们交付的内容是否真正提升了客户和用户的满意度。如果没有达到预期效果,相关功能可能会被重新开发甚至移除;同时也可以添加新的功能。
这意味着 Scrum 团队会不断变更和演进他们的产品增量,因此产品的稳定性至关重要,因为每一个新版本都是建立在前一个版本之上的。
虽然客户欢迎那些能帮助他们达成目标的新功能,但他们也期望产品中他们已熟悉的、满意的那部分体验保持一致。他们不希望每次收到新产品增量时都需要重新学习使用方式,也不愿意看到新版本出现不可预测的行为变化。
与此同时,Scrum 团队也不能每次发布新版本时都不得不重新开发大量已有功能。尽管他们可以预期根据客户反馈进行一定程度的重构与调整,但不能每次都从头开始开发。理想情况下,每个新版本应在不破坏已有有价值功能的前提下,新增功能。
随着 Scrum 团队不断为产品增量添加新功能,如果忽视了稳定性管理,产品可能会变得难以使用或维护。当团队走到这一步时,唯一的选择可能就是停止开发新功能,或者从头开始构建一个全新的产品增量。
此外,产品不稳定也会降低 Scrum 团队的效能。“创新能力(Ability to Innovate, A2I)”是基于实证管理的关键价值领域之一,衡量的是团队交付新功能和创新解决方案以更好满足客户需求的能力。A2I 的下降会进一步削弱团队产出有价值产品增量的能力。
导致产品不稳定的原因有哪些?
以下是一些可能导致 Scrum 团队在产品增量中引入不稳定性的因素:
- 未发现错误引发的质量退化
有时,Scrum 团队在添加新功能时,无意中破坏了之前正常运行的功能。这种问题在软件产品中尤为常见,但也可能出现在实物产品上。例如:改变了产品外观设计,导致某些按钮更难操作;或是将触控屏幕升级为更抗冲击材质,却降低了响应灵敏度。
采用“测试先行”的方法可以帮助团队减少或防止质量退化。如果这些测试实现了自动化,并结合持续交付实践运行,就能为开发者提供即时反馈,从而及时消除质量问题。
提高代码覆盖率(即测试覆盖了多少代码),也有助于发现潜在错误。
- 超出设计极限导致架构退化
产品就像建筑——一些看似简单的改动可能会导致整个系统发生严重故障。比如一栋建筑的屋顶原本设计承载一定重量,在接近设计上限时还能承受更多负荷,但一旦超过临界点,即使增加一点重量也可能导致屋顶坍塌。类似情况也可能发生在空调系统的升级中:为了应对更炎热的天气而提升冷却能力,可能会对整体结构产生不良影响。
“最小可行架构(Minimum Viable Architecture, MVA)”这一概念可以帮助 Scrum 团队确保每个产品增量具备足够的架构支持,既能保留过去的价值,又能探索提升用户体验的机会。MVA 的核心理念是:每个产品增量不仅要考虑其功能性需求,还要关注产品架构如何演化,以持续满足质量目标。
- 技术债务的累积
技术债务可以被看作是团队在开发过程中积累的一种“负债” —— 为了加快当前产品增量的交付,采取了一些权宜之计,从而牺牲了未来的生产力。这些捷径可能在稍后某个时间点需要重新修复。
需要注意的是,技术债务并不是未完成的工作,因为它已经满足了 Scrum 团队所定义的“完成标准”。
相反,技术债务是指那些在短期内看似高效、但从长期来看并不可持续的决策。例如,一个产品增量在最初设计时能够很好地满足早期用户的需求,但随着用户数量的增长,它可能无法支撑更大的使用规模。在该产品增量交付之时,扩展性问题并不明显;但如果产品最终获得成功并吸引了更多用户,那么某些部分可能就需要重新设计,以支持更大规模的用户访问。
一种减少技术债务的策略是:跟踪那些会增加技术债务的设计决策,并在每个 Sprint 中预留一部分团队产能,用于解决之前所采取的“捷径”。然而,如果这些权衡决策一再被推迟,或者技术债务持续增长,Scrum 团队就可能未能有效管理其技术债务,从而损害产品的长期可持续性。
- 未在所有产品变体中应用修复措施
当 Scrum 团队维护多个产品版本时,必须确保在一个版本中修复缺陷的同时,也在其他所有版本中同步修复相同的问题。否则,某些版本可能会因遗漏修复而导致质量下降。
一些降低成本的方法包括:
- 使用功能开关(Feature Toggles):只维护一个产品版本,通过功能开关控制不同行为,避免维护多个版本。
- 使用通用组件或共享平台:将更改限制在通用模块或共享平台上,只需修改一处即可生效。虽然仍需测试所有产品变体,但减少了重复修改带来的出错风险。
如何预防或减少产品不稳定?
除了上述提到的造成产品不稳定的原因之外,以下做法也有助于 Scrum 团队降低产品变得不稳定或不可用的风险:
- 投资可局部化变更的产品架构
模块化架构就像是船上的水密舱壁,可以防止一个问题影响到整个系统。这种“关注点隔离”的设计有助于降低产品不稳定的风险。
- 设计可替换性
有时候,Scrum 团队需要根据实证反馈调整之前的决策。提前使用接口和抽象机制,可以让实现细节的变化不会波及整个代码库。同时,记录架构决策也很重要,这样团队才能清楚哪些部分可能需要随之调整。
- 投入自动化回归测试和持续交付实践
每次代码变更后进行充分的回归测试,有助于 Scrum 团队防止缺陷潜入产品中。
- 持续重构代码以提升质量和减少技术债务
重构就像是重新整理行李箱或车库,让物品摆放更整齐。这是一种在不改变外部行为的前提下提升代码质量的技术。Scrum 团队如果能在每个 Sprint 中预留时间进行代码重构,就可以有效减少技术债务,提升代码的可维护性和可读性。
- 采用结对编程促进知识共享和质量提升
结对编程是一种由两名开发者共同编写同一段代码的做法。通常一名经验较丰富的开发者配合一名正在学习的开发者。这种方式不仅有助于提升团队成员的跨职能技能,也能通过多视角分析问题来提升代码质量。更重要的是,多人审阅代码可以在错误刚被写入时就发现并修正。
- 使用静态代码分析捕捉代码中的错误
静态分析是一种扫描代码以检测常见错误的技术,包括缺少文档、结构混乱、违反编码规范等。这对 Scrum 团队更好地理解其工作成果的质量非常有帮助。