敏捷:可能被开发人员遗忘的部分

译文
开发 前端
敏捷实践已经在全球范围内采用。而许多企业都以敏捷为荣,并且以不同的方式实现它。这很好,但并没有一个单一的方法来实现它,需要根据每个场景进行调整。

译者 | 李睿

审校 | 孙淑娟

如今,很多开发人员将太多的注意力集中在敏捷惯例上,而敏捷宣言中提到的关键方面没有根据它的重要性来考虑。  

敏捷实践已经在全球范围内采用。而许多企业都以敏捷为荣,并且以不同的方式实现它。这很好,但并没有一个单一的方法来实现它,需要根据每个场景进行调整。

高级软件工程师Jorge Fernández Rodríguez表示,过于关注敏捷的某些方面容易遗忘了另外一个关键方面。这不是什么新鲜事,但如果不考虑这一方面,发布软件的新版本可能是一个永无止境的故事。这就是要在本文中解决的问题。  

但在深入研究之前,先回顾一下软件开发的演变,先从瀑布和敏捷方法的诞生开始。

1.很久以前就采用瀑布方法  

许多在过去10年开始职业生涯的开发人员可能在敏捷环境中工作过。然而,敏捷并不总是存在。而在本世纪初,瀑布就是一种常见的做法。  

在瀑布方法中,应用程序通常是作为一个整体进行规划的,客户可能需要几个月才能看到一些可用的软件。

开发计划是作为一个项目进行的,而有了开头,在理论上也有一个结束(有时可能是公司倒闭)。该项目分为以下几个阶段:

  • 需求收集
  • 系统设计
  • 任务计划
  • 开发
  • 测试和交付

每个阶段通常由不同的人员进行。客户在开始和结束时都参与了合同的签署。如果项目成功完成,应用程序就会部署到生产环境中,并且通常会移交给另一个团队,该团队将负责保持正常运行。  

众所周知,这些做法造成了很多问题。其中一些是:  

收集所有需求、预先设计系统和规划任务几乎是不可能的,并且需要数周时间。  

每个阶段的交接都会导致沟通不畅。  

交付产品需要很长时间,并且实施很多次,远远超出预期。

在预算和范围内结束也很困难。  

阶段之间没有反馈循环。很多时候,只有最后才有反馈。如果反馈是否定的,那么整个投资都失败了。

2.敏捷解决关键问题  

Rodríguez表示,在他当初开始其职业生涯时就听说一个新概念:敏捷。当时并不知道这是怎么回事。那时他专注于提高开发技能,并不太关心软件开发方法。  

敏捷似乎解决了瀑布方法难以解决的许多问题,并迅速被采用。但许多人将其视为一种教条,认为采取一些惯例可以解决他们所有的问题。行业专家听到的最多的是一些流行术语,如:“Scrum”、“极限编程(XP)”、“Sprint”、“Retro”、“ Grooming”,以及其他一些术语(后来发现它们与精益更相关),例如“看板”、“ 进行中的工作(WIP)”。

大多数这些流行术语本身并没有告诉很多。在工作一段时间后,他开始对了解为什么很多企业都采用这些做法感兴趣,所以开始深入研究这个话题。  

他在工作中理解了其中一些术语的含义,并且看到了很多讨论:开发团队应该做Scrum、看板、极限编程(XP)还是其他?团队每个Scrum应该在每个惯例上花费多长时间?应该谈论什么?等等。  

他了解一些肤浅的信息,并且遗漏了一些信息。也许这是他的研究技能。回顾过去,发现不仅如此。  

当阅读敏捷宣言时,他了解其中一件事是:“个人和交互优于流程和工具”。  

在他工作的过程中,其印象是过于关注过程和惯例。这是第一个迹象表明,无论是谷歌的算法还是软件行业的某些部分都在关注不太重要的主题。  

同样值得澄清的是,有些人将这些原则解读为“第二部分并不重要”。然而,正如他多次听到的那样,这些原则应该被理解为:“尽管第二部分很重要,但第一部分更重要。”  

专注于敏捷的要点,与瀑布的主要区别之一是以增量的方式组织开发:应用程序将被划分为具有优先级的小块。每个块都是在一个Sprint内开发的(通常是1周或2周)。在每个Sprint之后,应该为客户提供应用程序的功能版本。客户(或者在某些情况下是业务代表)积极参与了该过程,因此可以尽早获得反馈。可以看到这些想法是如何解决瀑布方法出现的一些问题,它通过快速交付和通过早期获得反馈来快速失败。  

而在敏捷宣言中,其中一个价值观是“欢迎不断变化的需求,即使是在开发的后期”。一开始,Rodríguez无法理解这句话的含义,他不确定这是否是一个好主意。然而,在思考它并在敏捷环境中获得不同的经验之后,他认为它是最重要的部分之一。重要的是要考虑到变化可能涉及领域的新特征和新概念,但也可能涉及现有行为和市场的变化等。  

因此,不仅在敏捷中快速行动很重要(尽早交付客户需要的价值,通过早期反馈快速失败),而且对环境变化快速做出反应也很重要。它们不是唯一重要的方面,但以下将重点关注这两个方面。  

因此继续这种软件开发实践的演变,提到一些主要有助于快速发展的改进。  

3.快速行动:软件编码和交付实践的演变  

当时的工具并不容易采用敏捷实践,例如频繁部署。在过去的25年中出现了一些实践和技术,以帮助开发团队更快地发布软件。其中一些是敏捷的结果,而另一些则是独立出现的。  

Rodríguez简要提及其中的一些技术及其好处,而没有详细说明。他认为大多数都是广为人知的技术,但如果对人们来说是新技术,那么网上有很多资源可以找到更多信息:  

  • 测试自动化通过防止大量错误和减少调试需求为开发人员提供信心。
  • 版本控制帮助开发人员将更改追溯到添加时,轻松恢复更改,以更轻松的方式解决冲突,并且它是许多其他改进的基础。
  • 功能分支或与分支并行工作。具有并行性总是好的,这在很多情况下也带来了一个新问题:当进行大量更改或长时间保持分支打开时,开发人员需要花费大量时间来集成这些更改。
  • 功能标志。如果团队需要长时间并行处理多个计划,但希望避免长期存在的分支经常出现的冲突,这是一个选项。
  • 持续集成(CI)/持续交付(CD)。通过集成更改、运行测试和经常部署,交付到生产的巨大障碍正在消失。
  • 代码审查/配对编程。多年前,每个开发人员都在自己开发,甚至是关键代码。审查代码不仅可以帮助开发人员更好地编码,还可以分享知识、学习并减少遗漏重要内容的可能性。Rodríguez认为这并不总是必要的,但与对长期存在的分支进行大型拉取请求相比,它可以提供优势,因为反馈是在编码时提供的,避免了重新编写代码。
  • 开发人员构建并运行它。开发团队也开始负责维护应用程序。这很有意义,因为开发应用程序的团队比其他任何人都更能理解它,并且它带来了几个好处:
  • 发现问题的时间更少。
  • 解决问题时犯的错误更少。
  • 在生产环境中处理问题会带来宝贵的经验。这些有利于进一步的发展。
  • 由于不再需要交接会议,因此节省了大量时间。
  • 如果团队进行随叫随到的工作,软件的质量可以进一步受益,因为每个人都会尽最大努力避免在不适当的时间联系。
  • 团队结构的变化:组建小型、独立、跨职能的产品团队来打破IT孤岛。
  • 消除开发阶段之间的交接可加快交付速度,并避免沟通不畅。
  • 让团队更接近领域专家将对解决方案的质量产生积极影响,并通过减少场景切换等方式提高关注度。
  • 它还促进了系统的模块化(康威定律)。
  • 需要注意的是,跨职能人员并不是指全栈人员,Rodríguez认为这非常困难,甚至会适得其反。“T型开发者”的想法可能更有趣。
  • DevOps、容器、服务网格、分布式架构和云平台。基础设施变为自助服务(团队无需等待服务器分配即可部署)。它还变得不可变、易于替换、提高安全性等等。
  • 自动依赖项更新。
  • 更好的监控和事件管理,例如SLI/SLO、DORA指标和其他,以关闭反馈循环并做出更明智的决策。

除了这些实践之外,新工具、IDE改进、框架、库和语言演变使开发人员能够加快软件开发。  

如果企业采用上述大多数做法,这可能意味着软件可以比以前更快地交付。而且这些更改不仅更快而且更安全,因为许多任务都被自动化或委派了。  

有些人可能会认为软件交付就像闪电一样快,对吗?

根据Rodríguez的经验,即使遵循了这些做法,也可能需要很长时间才能实现价值。以下是一些案例:  

示例1:  

Rodríguez表示,他花费三天时间来理解必须修改的代码。这是他第一次接触到那个代码。值得庆幸的是,他正在与非常了解该应用程序的人一起工作。通过相应的测试来实施主要更改花费了开发团队两周时间。最后,他们花费大约16周的时间在整个代码中寻找错误并实施修复。  

正如人们所看到的,在第三点上花了很多时间。在这16周中,大约70%的人在寻找错误,大约20%的人理解开发人员发现的逻辑并考虑如何使其适应新行为,3%的人用于编写自动化测试,1%的人自己实施更改。  

以下是为什么花费这么长时间的一些原因:  

  • 服务做的事情太多了。
  • 代码耦合非常紧密,因为代码的不同部分发生了很多问题。
  • 与此同时,代码的内聚性不是很强。处理同样问题的逻辑被广泛传播。

示例2:  

Rodríguez表示,他们的研究团队花费三天时间了解需要改变什么,并花费一天的时间来实施这些更改,并花费七天的时间让测试再次通过。  

在这种情况下,开发人员正在修复代码以前的错误。其中一些甚至没有完全修复。很明显,一些开发人员对这些技术还不够熟悉。幸运的是,问题并不严重,客户也没有注意到。糟糕的是,它们在应用新更改时突然出现,使得测试几乎不可能,因此必须在完成任务之前修复它们。

另一个问题是堆栈不是最新的,开发团队想要实施的许多解决方案都行不通。在这些情况下,可能看到大量时间被浪费在调试和理解需要调整的代码上。  

除此之外,还有一些可以永远运行的构建通道(同一应用程序中的大量代码、缓慢或不稳定的测试等)。  

4.而被遗忘的部分是...  

采用了许多围绕软件开发的实践可以使其更快:敏捷、CI/CD、DevOps、团队结构等。但是,在更改现有代码的同时保持现有代码的工作可能是一场噩梦。大量时间仍然浪费在理解代码和四处寻找错误上,尽管已经存在了很多有用的实践。与此同时,围绕Scrum、看板、独立团队等有很多争论,而且,正如以上提到的,敏捷宣言并没有过多地关注特定的流程或仪式;它只是给出了一些一般性的想法。所以代码(测试)质量(尤其是灵活性)是敏捷中被忽略或遗忘的最重要部分之一。  

代码质量并不是敏捷的独有问题,但它在这里尤其重要,甚至比传统项目更重要。还有一种误解是,在敏捷方法中,不需要在软件架构和设计上进行任何计划或投入精力,但实际上恰恰相反。代码经常被扩展和调整,因此使系统易于更改至关重要,否则它们将使未来的开发变得非常缓慢。因此,对于敏捷开发,这句话的下一个迭代可能是:系统灵活性是敏捷中被忽略或遗忘的最重要部分之一。  

这并不是什么新鲜事。正如在以上内容看到的,敏捷宣言中提到了这一点,但持续关注卓越的技术和良好的设计可以提高敏捷性。  

敏捷流程促进可持续发展。赞助商、开发人员和用户应该能够无限期地保持恒定的速度。如果代码混乱、难以理解和变化,团队如何保持恒定的步伐?  

需要记住的是,质量并不意味着复杂性。简单也很重要:而简单就是最大化未完成工作量的艺术。  

架构通常与刚性和提前规划有关,因为经常想到难以改变的架构。从这个角度来看,在敏捷环境中投入时间在架构或设计上是没有意义的,因为事情经常发生变化。  

但是在软件世界中,可以选择让选项保持开放并使更改更容易的架构。事实上,敏捷促进了短期思维。众所周知,预测并不容易,开发人员最终付出了代价,甚至不知道两天后客户会需要什么。  

对于没有采用敏捷方法的开发人员来说,需要知道的是,高绩效员工不必以速度换取稳定性,反之亦然,因为通过提高质量,可以实现两全其美。

5.开发缓慢的后果  

随着开发人员添加更多代码,开发速度变得更慢,这不仅是开发人员的问题。每个利益相关者都用自己的方式说话,并且含义略有不同:  

  • 对于用户体验(UX)实验爱好者:实验可能需要数周而不是数天。
  • 对于产品爱好者:及时响应市场/满足客户需求……会发生吗?
  • 对于管理者:目标缺失,工作积压。
  • 对于DevOps研究与评估( DORA )指标爱好者:部署频率(DF)降低,变更的平均提前期(MLT)增加,变更失败率(CFR)增加。
  • 对于企业:即使开发人员有很好的想法,如果不能轻易地转化为软件,企业就会陷入困境。代码将是一种责任而不是一种资产,与此同时,竞争对手可能会利用。
  • 对于开发人员:不得不处理糟糕的代码可能会导致开发人员精疲力尽。

所以很明显开发速度会变慢,但幸运的是,如果投资于灵活的代码,可以节省一些时间。  

然而,要让一些人相信这一点并不容易。还有一个问题:僵化代码的效果不是立竿见影的。从长远来看,它们是可见的。在短期内投资开发灵活的代码可能看起来更慢。那么,谁愿意投资于没有立竿见影的效果呢?很多人的想法大多是短期的,需要更多地了解代码质量将如何影响未来的发展。  

6.将刚性系统的影响与业务联系起来  

严格的代码对开发某个产品需要多长时间的影响并不容易被发现。因此,对业务的影响也不明显。如果两者之间没有联系,就很难让人们相信拥有灵活系统的重要性。这是一个非常复杂的话题,但需要填补空白。  

DORA指标至少部分解决了这个问题。其代码不是同质的,代码路由很慢,问题可能被发现得太晚。  

软件架构师Glenn Engstrand在他的演讲中介绍的技术能力计划(TCP)在微服务架构中管理技术债务可能是一个起点。  

Rodríguez表示,他并没有一个理想的解决方案,梦想有一个在每次提交后更新的分数,它可以用作估计未来任务需要多长时间才能完成的乘数。  

然而,想以一些关于如何提高代码灵活性的简单想法作为结束。

7.提高代码灵活性的思路  

网上有很多关于代码质量的书籍和资源,因此就不再赘述:  

  • 代码需要易于理解。通过阅读方法名称,应该清楚它的作用。例如,理解一种方法不应超过10秒。
  • 代码需要模块化。模块,松散耦合,封装。这适用于每个级别:系统、库、包、类和方法。
  • 代码需要有凝聚力。每个部分只需要做一件事,并且做这件事的所有代码都需要紧密结合在一起。
  • 将业务逻辑与控制器、侦听器、过滤器等框架结构分开尤为重要。
  • 代码需要简单(不要过度设计,不要强行引入设计模式)。
  • 针对当前需求进行开发。当开发人员想:“如果我们需要X功能怎么办?”,采用YAGNI。

对于测试,需要记住它们提供安全性,但它们抵制更改,并且可能会比生产代码本身占用更多的时间,因此:

  • 他们需要带来足够的价值。进行测试驱动开发(TDD)是一种可以帮助企业实现它的实践。
  • 如果他们测试实施细节,他们将很难改变。

很多单元测试来验证提供内部结果的代码片段。这些代码是开发人员组织代码的结果。如果逻辑需要以不同的方式组织和移动,许多测试就会中断。发生这种情况时,测试不再保护并且几乎毫无用处。它还给团队额外的工作。因此,重要的是要考虑什么是实际的单位。在不得不多次重组代码之后,Rodríguez表示一直在思考这个问题,开始认为单元的概念可能不仅仅是方法或类,而是可能需要从特性的角度来考虑。这可能听起来很奇怪,并且类似于集成测试,但事实并非如此。

  • 支持更简单、更快速的测试:单元优于集成。考虑应用层面的集成;集成测试应该处理单元测试中无法验证的事情,例如与框架的集成。
  • 在默认情况下,并非每个功能都需要端到端测试。它们对于可能危及生命、个人可识别信息(PII)至关重要、可能使企业损失大量资金或类似情况的功能非常重要。

8.结论  

如果开发人员需要经常引入更改,保持系统的灵活性至关重要,就像在敏捷环境中一样。否则在一段时间后,合并更改将变得越来越困难。其他做法将帮助暂时弥补这一点,但最终它们的影响将不那么显著。很多时候,帮助开发人员保持代码灵活性的实践非常容易应用。

每天都有更多的证据支持这样一个事实,即质量有助于保持持续的发展速度。此外出现了一些新的想法,可以将僵化代码在业务中的作用联系起来。

原文链接:https://dzone.com/articles/agile-forgotten-parts

责任编辑:武晓燕 来源: 51CTO技术栈
相关推荐

2019-09-03 10:12:15

开发者技能工具

2010-08-09 16:09:25

2009-12-11 14:50:14

Visual Basi

2009-11-23 20:07:51

ibmdw开发

2021-02-19 09:33:01

kubernetesJAVA服务

2012-05-30 15:15:42

ibmdw

2023-03-15 07:12:53

企业开发人员提供商

2021-02-16 16:44:40

RustJavaScript开发

2022-01-06 16:15:58

自测测试开发人员

2021-01-12 14:37:09

开发科学写作

2021-12-28 13:34:52

开发者开发者体验云供应商

2010-08-16 09:21:35

Windows Pho

2012-12-14 08:55:45

开发人员产品经理

2021-12-10 23:48:19

Java开发技术

2009-07-20 16:11:41

JRuby Swing

2023-02-17 15:01:15

2019-11-27 18:54:07

物联网数字孪生机器学习

2011-09-05 14:21:29

webOS

2013-04-15 10:00:09

程序员

2009-05-31 08:31:07

GoogleWaveTechCrunch
点赞
收藏

51CTO技术栈公众号