关于敏捷方法的批判性思考

本文对敏捷方法进行了深入的批判性分析,从敏捷方法的核心价值观出发,详细探讨了实践中的常见误区,包括形式化套用、对文档的误解、需求变更的误区等问题。同时从产品特性、团队规模、项目紧急性等多个维度分析了敏捷方法的适用场景和局限性,为软件开发团队正确选择和使用敏捷方法提供了理论指导和实践建议。

1. 敏捷方法简介

敏捷软件方法是一种以人为核心、迭代、循序渐进的一种新型软件方法,从 1990 年代开始逐渐引起关注。

"敏捷"一词最早源于 2001 年的雪鸟会议,与会者共同起草了著名的敏捷宣言,即四个"高于":

  • 个体与互动高于流程和工具
  • 工作的软件高于详尽的文档
  • 客户合作高于合同谈判
  • 响应变化高于遵循计划

尽管右项有其价值,但我们更重视左项的价值。这就是敏捷方法的核心价值观。

敏捷方法涵盖了并描述了多个开发方法,这些方法包括:

  • 极限编程(XP)
  • Scrum
  • 精益开发(Lean Development)
  • 特征驱动开发(FDD)等

这些方法各有侧重,但都是敏捷核心价值观的体现。最常见的敏捷方法要数 XP 和 Scrum。因为 XP 关注的是实际的编程实践,而 Scrum 注重的是管理和组织实践,所以在实际中两者往往被结合使用。每一个敏捷方法又包含了一系列的实践,以 XP 为例,它包含了结对编程、测试驱动开发(TDD)、持续集成(CI)等 13 个核心实践。

区别于其他软件开发方法,敏捷方法有两个重要的特征:

  1. 敏捷是"适应性"的而非"预设性"的
  2. 敏捷是"面向人"的而非"面向过程"的

敏捷方法的"适应性"是为了应对软件开发中"易变性"这一本质困难。与土木工程等传统的工程相比,软件开发的一个难点在于需求的不稳定性,这直接导致了软件过程的不可预测。传统的开发方法试图在一个很长的时间跨度内对软件项目做出一个详细的计划,然后按照计划进行开发。这种做法的缺点是显而易见的,即很难适应变化。而敏捷通过"分级需求"、"快速迭代"等方法大大减少了变化造成的影响,从而做到"响应变化"。

在传统的软件开发中,团队项目分配工作的重点是明确角色定义,以个人的能力去适应角色,而角色的定义就是为了保证过程的实施。而敏捷方法试图使软件开发工作能够利用人的特点,充分发挥人的创造能力。敏捷要求一个项目团队全员参与到软件开发中,研发人员在技术上可以独立自主地决策。此外,敏捷开发还特别重视项目团队中的信息交流,认为面对面的沟通比书面的文档更有效。

2. 敏捷实践中的误区

随着敏捷方法的盛行,越来越多的团队尝试在项目开发过程中融入敏捷的思想,但是效果却并不理想,有些人因此对敏捷方法产生了质疑。诚然,敏捷方法不是"银弹",它也有一些解决不了的问题和不适用的场景,但是这些项目失败的一个很大原因并不在敏捷本身,而是在使用敏捷时陷入了误区。

误区 1:为了敏捷而敏捷

敏捷作为一个被广泛接纳的开发模式而受到越来越多的人的关注,越来越多的团队尝试着向敏捷转型。而这其中存在不少失败的案例,它们多半是对敏捷存在理解的误区,仅仅只是为了使用敏捷而披上了敏捷的形式化的"外套"。很多失败的案例中只是在强行套用敏捷的形式,在遇到问题的时候有时还会切回自己以前习惯的开发模式,这样的做法只会导致事倍功半。

在是否使用敏捷作为开发的指导模型这一问题上,我们应当提倡实用主义,敏捷虽好,也需要针对实际情况慎重选择,如果敏捷不能解决当前所遇到的问题,那么强行套用敏捷只会带来更大的麻烦。而在决定使用敏捷时,同样需要注意不要生搬硬套,形式上的敏捷不能解决任何问题。

误区 2:敏捷是反文档的

敏捷宣言中提到:"可以工作的软件胜过面面俱到的文档",这一点往往容易让人们形成一种误解,那就是在敏捷过程中文档书写占据无关紧要的位置,文档没必要写的过于详细,甚至于有人认为敏捷就是反文档的,在敏捷的环节中抵触文档。

针对这一点,我们首先要清楚文档的本质是将知识显性化。对于一个项目中隐性的、需要一定的沟通代价的知识,通过文档的形式将其显性化是为了有效的沟通。传统的观念中忽略了文档所带来的代价,尤其是更新同步文档所带来的代价,对于某些知识仅需通过口头交流就可以做到很好的沟通的情况,仍然使用文档化作为沟通手段就会显得效率低下。然而完全舍弃文档同样是一种不合理的做法,每一次都需要对着不同的人通过口头的方式尝试让他们理解,并且信息的口头传述显然会有一定的损失,这样只会是更加低效的做法。

所以,针对敏捷,我们首先要明确项目中什么类型的知识是必须被显性化的,什么样的知识是可以保持隐性的。对于前者,通过文档化的形式使得重要的知识不会在传递和沟通过程中受到过多的损失,同时避免不必要的重复交流。对于后者,通过口头交流的方式降低写文档的成本与阅读文档时理解的成本。

误区 3:"拥抱变更"等同于需求可以随意变更

正如《人月神话》所言:"在软件开发领域中,唯一不变的就是变化本身",所以敏捷宣言强调:"响应变化胜过遵循计划"。但这不意味着敏捷对需求的变更控制弱化,允许对需求随意进行变更。

敏捷仍需要对需求的质量进行审核,如果从一开始在需求上就犯了方向性上的错误,这对于一个团队来说将是极为致命的,其后续的工作可能都会因此变得毫无意义,所以对需求进行慎重的评审以确保其基本的质量对于敏捷而言仍然十分重要。在敏捷的一次迭代周期中也要尽量避免频繁的需求变更,频繁的响应变更会使得一个团队没有明确的方向与目标,损耗团队成员的成就感。此外,敏捷是重视业务价值导向的,对于一个需求的变更,如果从业务价值的角度来看并没有太大的意义,那么团队也不需要急切地响应这一变更。

误区 4:"快速迭代"意味着频繁更新

有人认为,"快速迭代"意味着软件版本频繁地更新,极端的做法是每天都会有一个新的版本。过于频繁的更新会导致三个问题:

  1. 从用户角度来看,软件更新耗时麻烦,并且需要考虑流量费用等问题
  2. 从项目过程角度来看,这会导致下游工作如发布等无法正常进行,因为软件的发布可能会需要一定的审核时间
  3. 从产品本身的角度来看,频繁的更新意味着产品没有经过足够的测试,可能无法稳定地运行,在实际使用中可能会出现各种各样的 bug

敏捷方法提倡的"快速迭代"应该是针对需求的迭代。在互联网时代,用户的需求往往是模糊的、不确定的,敏捷希望能够对可能的需求进行快速地响应,快速地推出产品,然后从用户的反馈中验证需求并获取新的需求,然后开始下一个迭代。从这个方面来看,"快速迭代"的确与版本更新有一定的关系,但更新的版本应该是有新的功能、新的用户体验的版本,而不是对 bug 的小修小补。而现实中,很多团队都是先发布一个版本,发现 bug 之后又很快发布新的版本,每个迭代周期过短,并且只是修复 bug,而不是以需求作为迭代的中心。对此的建议是,对于不是特别严重的 bug,应该收集反馈、统一修订后,再发布新的版本,每次迭代仍要以需求作为重点。

误区 5:敏捷是自由的、无约束的

敏捷强调团队的自组织,让人有自由的、无约束的错觉。敏捷宣言的十二条原则中提出"激发每个团队成员的积极性来打造项目,为他们提供所需的环境与支持,并且信任他们能够完成工作"。这实际上有两个潜在的要求:

  1. 团队成员的自觉性,或者是职业操守(不只是为了工资在工作)。任何一名团队成员的消极怠工对整个团队的积极性都是一个严重的打击
  2. 项目领导的团队领导能力,而不是管理能力。敏捷要破除"官僚",所以这里强调的是领导能力而非管理能力,这两者的一个显著区别在于领导能力是使团队成员自愿跟随而非强制管理

所以敏捷并不是绝对自由、无约束的,它需要团队成员的自我约束以及领导者的正确领导。很多团队做不到这两点,所以使用敏捷造成问题也是理所当然的。因此,在尝试使用敏捷时,应该充分考虑这两个因素。对有些团队而言,严格的管理仍然是必要的,敏捷也许并不适合他们。

3. 敏捷方法适用与不适用的场景

从产品的角度来看

敏捷方法适用于需求容易变更的产品,不适用于对可靠性、安全性等方面有着较高要求的系统和复杂的大型系统。

在软件开发过程中,与需求有关的问题主要分为以下三类:

  1. 从用户提出需求到程序员开始开发这一漫长的需求传递过程中,关键信息发生丢失
  2. 用户不清楚自己的需求是什么,他们对于需求的描述不准确,这导致了开发人员理解的需求和真实的设想差别进一步扩大,开发出现严重偏差
  3. 在移动互联网高速发展的背景下,需求本身可能每天都在变化,即使用户对于需求的描述准确和交流完全没有差错,但等到软件产品交付后,需求可能已经发生了重大变化

敏捷方法通过"分级需求"和"快速迭代"等手段可以很好地应对以上的需求问题,但这种开发模式也决定了敏捷方法对软件的容错性要求不高,因此对于在可靠性、安全性等方面有着较高要求的系统而言,敏捷方法很可能并不合适。例如登月程序控制软件,它要求极高的安全性和可靠性,并且需求较为稳定,敏捷方法在这种项目中并没有什么帮助。

另外,对于大型系统而言,需要考虑系统特性、与其他系统的通信和集成、不同用户群的需求等多个方面的因素,因此大型系统往往伴随着较高的复杂度,并且同时有很高的安全性和可靠性要求。面对这样的系统,敏捷的每次迭代都需要经过严格的验证,要处理的问题十分复杂,很难在满足要求的同时做到"快速",这违背了敏捷的初衷。

从人员组织结构角度来看

敏捷方法适用于规模较小并且沟通顺畅、彼此信任的开发团队,难以适用于大型的开发团队。

敏捷方法旨在通过敏捷团队的运作,激发出每一个成员的最大潜能,以最大合力完成软件产品开发。在这样一个自组织的团队中,每一个成员都能为项目充分贡献自己的力量,每一个成员都是项目的主人,并且成员之间有着充分的技术交流和沟通分享,在这种技术交流和沟通分享的过程中又能提升开发人员自身的能力和水平,从而达到个体战力的最大化。

在团队建设中,一个可以想象的问题是,团队规模的扩大会导致沟通成本的增加,组织结构上需要介入更多和项目无关的人员进行管理,这无疑会降低团队成员的积极性与参与感。因此,在一个严重依赖个人主观能动性的敏捷项目中,人数太多反而是一个灾难。此外,类似于极限编程这样的敏捷方法只适用于 7 至 10 人的小型团队,将大型团队拆分为几个小团队则会导致交流成本成倍扩大,管理成本严重超支。因此,敏捷方法更适用于短小精悍的开发团队,至少从目前来看,大型开发团队采用敏捷方法是不合适的。

从软件项目的紧急性角度来看

敏捷方法适用于那些有着激进的时间限制的项目,如果项目没有严格的时间限制和督促,可能就没有使用敏捷方法的必要。

系统开发周期和维护周期也是在选择软件开发方法时需要考虑的因素。通常大型系统所需的开发和维护时间较长,并且需要关注可能的变更和重新设计,还可能会被要求交付不同的版本。如果一个项目没有比较高的紧急度,综合考量其他因素,敏捷方法可能就不适用这个项目,因为敏捷方法中的一些实践,例如时间箱管理等,就是为了保持项目开发过程中的紧张度和专注度而存在的。如果项目本身并没有紧急性,那么可能就没有使用敏捷方法的必要。

4. 总结

敏捷方法是一个实用的工具,互联网时代的软件开发特点使得敏捷方法有了大显身手的平台。只有工具是不够的,我们还应该学习如何正确地使用它,错误的使用可能会适得其反。此外,敏捷方法不是"银弹",它也有不适用的场景和解决不了的问题。如何正确使用,什么时候该用,什么时候不该用,只有明确了这些,我们才能够真正享受到敏捷方法带来的好处。

评论

后继续评论需要管理员审核后可见

暂无评论,来发表第一条评论吧