敏捷-我们做错了什么?


22

我是敏捷团队的开发人员,我们尝试使用Scrum。

因此,我将在此处提出一个假设问题来说明这种情况。

我们有一个非常老的应用程序,使用了一些凌乱且糟糕的可维护性JQuery代码。我们也有部分使用React的应用程序,这些部分更易于更新/维护。除此之外,公司的目标是在React上开发一个客户端单页应用程序,因此使用JQuery可以使您走得更远。

在进行规划时,我们总是会在开发时间方面寻求简单的解决方案,因此例如,如果我们要创建新对话框或其他内容,我们会使用旧的JQuery,因为它的速度更快,并且我们说我们要回去后来整理并转化为React,但这很少发生。

我们从用户故事中获得了我们必须做的事情的要求(IMO做得很好,虽然很苗条,但是它们可以解释我们在做什么,以及为什么要这样做)。

有时,对新功能的要求非常渺茫,例如,如果某个要求说“创建一个加载大量内容的对话框”却没有说要实现加载功能,那么在大多数情况下,我们不会实现它,尽管我们都知道这对客户会更好,因为这样做可能会损害我们的sprint目标(即使我个人认为不会)。

结果是我们的代码库混乱不堪,可维护性很差,并且新功能有时非常小,需要花很多时间(在良好的代码库中一天就可以实现),这主要是因为此开发策略,快走,做到极简。

在这种情况下,我们做错了什么?我们是否应该以更完整的方式解决解决方案,以便我们不浪费编写糟糕的代码并重写上周刚刚编写的代码?还是应该确保仅重写所有代码,就继续这样做?什么是解决此问题的敏捷方法?


21
“结果是我们的代码库混乱不堪,可维护性很差,主要是因为这种开发策略使程序运行起来很快,却花了最少的时间。” -听起来您已经对这个问题有了一个很好的主意,但是我不确定这真的与敏捷有很大关系。无论使用哪种方法,都可以得到胶带编码。
Nathanael

如何预防敏捷?人们将增量理解为鸭子编带然后固定。
加布里埃尔·斯洛姆卡

7
“人们将增量理解为鸭带然后固定。” -当然不是什么混乱。如果“人”这样认为,他们就会误解scrum。
Bryan Oakley '18

9
引用埃里克·利珀特(Eric Lippert)的话:如果您自己钻进一个洞,要出去的第一件事是:停止挖掘。
布朗

5
您的团队是否遵循“童子军规则”(将位置始终保持比进入时更好的状态)?从那开始。此外,代码审查,编写测试和常规重构也是有用的技术。
布朗

Answers:


56

这与敏捷或Scrum无关。

“现在将其录音,我们稍后再修复”的问题是,以后再也不会出现,与此同时,您还积累了很多技术债务

恢复的第一步是识别问题,并使其不再恶化。

对于每个新的用户故事,团队应该考虑“什么是编写此代码的正确方法?”,而不是“什么是破解此问题的最快方法?” 并据此计划冲刺。

要清理现有问题,请参阅对我继承了200K行意大利面条代码的出色答案-现在怎么办?


另外,我觉得大多数这样的问题是由于没有经验丰富的经理知道如何解决这些问题,而是用网上阅读的命名方法代替了经理。这样做的一个好处是现在该方法由管理者来负责了。
罗布

1
答案就是这样。好放,非常精确。SCRUM只是一种工作方式,如果您决定使用胶带而不是整理带,那就麻烦了。
coteyr

您得到了激励。如果您使人们承受持续不断的截止日期压力(Scrum的冲刺),那么您正在激励人们采取捷径。因此,技术债务不断累积。
Michael B

22

您所拥有的就是马丁·福勒(Martin Fowler)所说的“疲倦的混乱”。

如果您正确阅读了《敏捷宣言》背后的所有12条原则,您会发现自己大部分都失败了。

频繁交付工作软件,从几周到几个月不等,而更倾向于缩短时间。

您能否说您交付了真正有效的软件?还是仅仅是行不通的软件?

敏捷过程促进可持续发展。赞助者,开发者和用户应该能够无限期地保持恒定的步伐。

你能说你的过程是可持续的吗?您在制定决策时会考虑到可持续性吗?还是您选择了解决当前问题而又不考虑长期影响的解决方案?

持续关注技术卓越和良好的设计可提高敏捷性。

真正的主要原则。我认为这应该放在页面上的“大红色字母”中。这是您最失败的地方。

团队会定期思考如何提高效率,然后相应地调整和调整其行为。

最明显的是 如果您发现自己的行为并没有达到预期的结果,则应该对其进行更改。如果您的团队看不到问题,那么它将无法开始解决问题。

根据您的评论

如何在敏捷中预防这种情况?

首先,通过学习实际的敏捷性。Scrum不敏捷。有人会说Scrum在敏捷框架中是最糟糕的,因为要达到您的实际情况太容易了。您应该了解其他敏捷框架。我推荐的是极限编程。显然可以解决您的问题。解决方案并不简单(通过强大的自动化测试,结对编程和连续交付来专注于技术卓越),但是却非常有效。如《 DevOps状态》报告中所述


6
“有些人会说Scrum ...太容易达到您的实际情况。” 。我不认为那是真的。错误地执行scrum 可能会导致这种情况,但是scrum本身不支持最便宜的解决方案,除非客户正是想要的。
布莱恩·奥克利

1
@BryanOakley我想说的是,如果流程未规定执行X,那么人们将不会执行X。Scrum也未规定任何减少技术债务的做法。恰恰相反,如果采购订单仅定义了要完成的工作,则不会消除任何技术债务。由于PO没有理由在意它。技术债务仅是团队的责任。
欣快的

2
“ Scrum没有规定任何减少技术债务的做法。” -也没有规定任何增加技术债务的做法。
Bryan Oakley '18

2
@BryanOakley技术债务的重点是它增加的自然状态。并且必须努力减少它。任其发展,它将无法控制地增长。
欣快的

4
如果PO是唯一获得有关sprint信息的人,则PO的作用很差。通过与参与生产过程的所有人(包括团队中的其他成员)进行交谈,确定最重要的事情是他们的工作。
Erik '18

9

您所描述的是-至少根据我的经验- 团队尝试“敏捷”的一种非常普遍的新兴模式。如果这实际上是敏捷本身的一部分或它的常见错误实现,违背敏捷清单/原理或它的内在后果,则可以进行辩论。从经验的角度来看,仅基于我自己的少量经验样本(以及与我交谈的人),如果团队敏捷,那么进入这种模式的机会似乎要比平均水平高。让我们继续讨论一下,重点关注您的具体示例。

您所描述的内容分为两个方面

  • 缺乏共识/愿景,因此效率不高
  • 如何衡量成功/进展和总成本

走错路或盘旋

以我的经验,发生这种情况的主要原因是,为了快速生成代码,团队积极地搁置了他们已经知道或很容易发现的用例或需求。这样想吧:10到20年前,人们试图编写巨型规格并事先考虑所有事情,但常常失败。他们花了太长时间或忽略了一些东西。过去的经验之一是,在软件开发中,有些事情是您不知道的,并且事情发生了很大的变化,因此,需要快速迭代并快速产生有意义的输出的想法。这是一个很好的原则。但是今天,我们处于另一个极端:“我不在乎,因为它是下一个冲刺的一部分”或“我不提交该错误,而是在再次出现该错误时进行处理”。

  1. 收集您可以找到的所有高级用例,需求,依赖性和限制。将其放在一些Wiki中,以便所有涉众和开发人员都可以看到它们。出现新情况时将其添加到他们。与您的股东和用户交谈。在开发时将其用作检查清单,以防止实施对最终产品没有帮助的事情,或者是解决了一个问题却导致三个新问题的变通办法/黑客。
  2. 制定高层次的概念。我不是在谈论设计接口或类,而是大致勾勒出问题领域。最终解决方案中的主要元素,机制和相互作用是什么?在您的情况下,当使用jquery-workaround帮助作为中间步骤并且仅引起其他工作时,它应该很明显。
  3. 使用您收集的列表来验证您的概念。是否有任何明显的问题?是否有意义?是否有更有效的方法来实现相同的用户价值而又不会造成长期的技术负担?

不要过分。您只需要一些东西,以便团队中的每个人(包括非开发人员)都可以共同理解实现MVP的最佳途径。每个人都应该同意没有明显的疏忽,并且实际上可以奏效。通常,这有助于防止陷入僵局或多次重做同一件事。敏捷可以帮助您更好地应对意外情况,无可置疑地忽略已知的内容。

注意沉没成本的谬误:如果您从一种架构或数据库类型入手,大多数人会在项目中期更改它。因此,在开始实施某些东西之前,花一些时间进行“有根据的最佳猜测”是一个好主意。开发人员倾向于快速编写代码。但是通常有一些模拟,实时原型,屏幕截图,线框等,它们的迭代速度甚至比编写代码还要快。请注意,编写的每一行代码甚至单元测试都使再次更改整体概念变得更加困难。

衡量成功

一个完全独立的方面是您如何衡量进度。假设您的项目目标是使用周围的东西建造一座高1m的塔。如果例如上市时间比稳定性更重要,那么盖一栋纸牌屋可能是一个完全有效的解决方案。如果您的目标是建立持久的东西,那么使用Lego会更好。关键是:什么被认为是hack,什么优雅的解决方案完全取决于如何衡量项目的成功

您的“加载”示例非常好。过去,我有这样的事情,每个人(包括销售,采购订单,用户)都认为这很烦人。但这对产品的成功没有影响,也没有造成长期债务。之所以删除它,是因为开发资源还有更多有价值的事情要做。

我的建议是:

  1. 保持一切,哪怕是很小的错误,因为在你的票制度的门票。做出积极的决定,在项目范围之内,什么不在项目范围内。创建里程碑或以其他方式过滤您的积压订单,以便始终获得所有仍需要完成的工作的“完整”列表。
  2. 具有严格的重要性顺序和明确的起点,在该起点上可以认为该项目是成功的。最终产品实际需要什么级别的稳定性/代码质量/文档?通过从顶部进行选择,尝试尽可能多地度过每一天的工作。处理一张票证时,请尝试在不引入新票证的情况下彻底解决该问题(除非由于优先级较低而推迟处理)。每次提交都应使您朝着自己的最终目标前进,而不是向侧面或向后前进。但要再次强调一下:有时候,在以后产生更多工作的黑客仍然可以对项目产生积极的影响!
  3. 使用您的采购订单/用户来确定用户价值,但也要让您的开发人员来计算技术成本。非开发人员通常无法判断真正的长期成本(不仅仅是实施成本!),因此请帮助他们。注意“青蛙青蛙”问题:随着时间的推移,许多无关紧要的小问题会使团队陷入僵局。尝试量化团队的效率。
  4. 密切关注总体目标/成本。而不是从一个Sprint到另一个 Sprint来思考,而是要保持“我们作为一个团队可以在项目结束之前做所有必要的事情”的思路。冲刺只是一种分解事物并具有检查点的方法。
  5. 与其希望早点展示,不如将您的课程安排在最快的道路上,以提供给用户的最低可行的产品。不过,您的总体策略应允许在两者之间取得可验证的结果。

因此,当某人做了不符合您最终实现目标的事情时,最好不要考虑已完成的故事。如果关闭故事很有帮助(例如,从客户那里获得反馈),请立即打开一个新的故事/错误以解决短期问题。明确表示采用快捷方式不会降低成本,而只是隐藏或延迟它们!

这里的技巧是要与项目的总成本进行争论:例如,如果采购订单要求采取捷径来制定截止日期,则要量化随后要考虑的项目工作量!

还要提防基于标准的优化:如果您的团队是根据他们在sprint审查中可以显示的故事数量来衡量的,那么获得良好“评分”的最佳方法是将每个故事切成10个小故事。如果以编写的单元测试的数量来衡量,则倾向于编写很多不必要的单元测试。不要计算故事,而是要衡量所需的用户功能有多少工作,在项目范围内解决的技术债务成本有多大等。

摘要

归结为一点:快速而精简是一个好方法。牛逼,他的问题是在解释“快”和“最小”。人们应该始终考虑长期成本(除非您有一个与之无关的项目)。使用仅需1天但在交货日期后1个月就会产生技术债务的快捷方式,比花费1周的解决方案要贵的公司多。立即开始编写测试似乎很快,但是如果您的概念存在缺陷并且巩固了错误的方法,那就不会很快。

请记住,“长期”在您的情况下意味着什么:我知道一家以上的公司因试图编写出色的代码而破产,因此交付太迟了。从公司的角度来看,好的架构或简洁的代码只有在实现它的成本小于没有它的成本时才有价值。

希望有帮助!


“这样想:10到20年前,人们试图编写大型规格并事先考虑所有事情,但常常失败。”:从90年代开始从事这项业务,好吧,不,我们没有那样做。可以说,这只是营销常识,它与敏捷的历史形成鲜明对比,在过去,人们因计划过多而犯错。在1998年前后,我学到了第一批课程,其中包括不要计划太多和制作早期原型。敏捷运动在某种程度上只是将新词用于知名做法,然后将其推广为新词。
乔治

当然,这当然取决于自己的经验。实际上,我在一些大型的,保守的汽车制造商的项目中工作,并且您不相信在编写一行代码之前,规范的详细程度如何。尽管我所描述的是一个极端,但如今有许多公司没有进行适当的成立(这是我过去从未经历过的)。在这两个极端之间,频谱上的每个点总是有例子。但是我至少看到,总体趋势已朝着“从不开始”的方向发生了相当明显的变化。
AlexK,

7

从scrum角度严格来说,这听起来好像您在做错事情是您没有客户一起工作。您需要与客户一起工作,以了解他们的需求,而不仅仅是他们的需求。他们需要一系列快速解决方案,还是需要一个稳定,可维护的系统来长期服务?这可能很难确定,但是质量与背景色或性能基准一样重要。客户需要意识到稳定性和可维护性不是免费的,必须将其设计到产品中。

如果他们说是前者,那您就没做错什么-假设您在sprint审查中向他们解释,您在偷工减料以满足他们的目标。

如果他们说是后者,那么您做错了就是您没有给他们他们想要的东西。

Scrum的基石之一是透明度。如果您正在做Scrum,则应该与客户进行冲刺审查。在这些评论中,您是否要告诉客户您在偷工减料以便更快地交付软件?如果不是,你应该是。您需要与客户100%地了解设计选择的后果,以便他们有机会就是否以适当的质量级别交付软件做出明智的决定。


3
与客户合作时,请确保您弄清楚他们的需求,而不是他们说的想要。几乎所有客户都会为每个问题选择最便宜,最快的解决方案,工程团队的工作就是弄清楚最便宜的选择是什么,仍然可以覆盖他们真正需要的所有东西。
Erik

1
@Erik:极好的评论。这就是为什么我最初写_“以了解他们的需求”而不是“ ...他们想要的”的原因。但是,我看到的强调不是很多。我将添加更多的强调和解释。感谢您的评论。
Bryan Oakley '18

5

伊万是对的 管理喜欢scrum的原因是因为他们以断断续续的样式来需求功能并快速获得结果。直到结果混乱是别人的问题。

现在,请注意,请让我解释一下。并非如此。这是一个强大的产品经理和一个软弱的开发团队的典型背景,他们无法承受压力,无法做出合理,切合实际的估算。因此,他们提出了远远超出乐观的估计,并使自己陷入更大的麻烦,为了及时交付而偷工减料。

在Scrum中,您(作为开发人员)可以进行自己的计划。没有人告诉您在x天内提供某些功能。如果有人告诉您要在x天内交付,则说明您不是在做Scrum。

无论问题是什么都需要解决,请花点时间。您是否认为需要时间先进行某些返工?将其纳入您的估计中。你能负担得起吗?


3

让我们检查一下您在做什么,暂时搁置敏捷。

在进行规划时,我们会在开发时间方面寻求简单的解决方案,因此,例如,如果我们要创建新对话框或其他内容,我们会使用旧的jquery,因为它的速度更快,并且我们说稍后再返回整理并转变为反应,但这很少发生。

这称为“承担技术债务”。马丁·福勒(Martin Fowler)在博客文章中沿两个轴描述了“技术债务象限” :“鲁eck vs.审慎”和“故意vs.无意”。

您明确决定使用已知的技术jquery,使您远离一个明确的目标(即单页应用程序)。您这样做是为了“快速”交付。这是故意的。

这种“快速”计算不包括您随后需要实现功能的时间。根据对速度至关重要的评估,您选择的替代方案仅比您知道是正确的替代方案(即花时间在响应中实现该功能)不利。这是鲁Re的。

马丁·福勒(Martin Fowler)将此类债务归纳为“我们没有时间进行设计”。在您不希望维护代码,甚至不希望编写几天以上代码的环境中,这是一个适当的选择。但是您的项目是一个长期运行的项目,明确涉及对客户的维护

从根本上讲,您正在做的事情是错误的。这是不好的工程

您承担了技术债务,而忽略了该债务需要偿还收取利息。并且您一直这样做,直到您的债务利率在冲刺期间开始接近可用工作为止。

您应该做的是减少债务水平。与老板交谈,与客户交谈。您昨天需要进行可维护性工作。


2

停止使用敏捷...

或者更确切地说,停止尝试以某种方式做某事,纯粹是因为那(您对敏捷(或混乱)等的理解)指示了这一点。在错误的阶段尝试对这些术语之一进行(错误)解释会很快成为最糟糕的行动。请改用您的理由。

您的项目以及世界上几乎所有其他项目都是混乱的代码和不同的方法的原因是由于缺乏集中的,无所不知的建筑设计(我曾说过)。

可能缺少的原因是:

  • 架构师没有专业知识(就像您的前十个业余项目一样)
  • 建筑师没有时间
  • 架构师没有权力(经理说不,或者是,但仅适用于某些部分)
  • 团队对可以拯救他们的伏都教具学方法充满信心(因为我们使用的是敏捷方法,所以它们都将被淘汰掉)

一种简单的解决方案是丢弃所有这些不可思议的词,并查看实际情况,可以将其总结为:

  1. 代码状态阻碍了团队按时交付和消除错误的能力。
  2. 我们添加的功能越多,效果就会越差。
  3. 因此,暂停,重新评估和(或大幅度地)重新设计零件确实有意义。

您自然会问起为什么它会首先到达这种状态,而责备的手指却一圈又一圈地旋转。答案是,这是不可避免的:随着设计的成熟,您意识到应该以不同的方式来做,但是您无法预见到它。此外,这不是每个项目一次的实现,它会发生多次,因此您需要为此计划。

话虽如此,经理们可以做很多事情来加剧这种情况:

  1. 让您的开发人员按时完成任务。
  2. 声明开发人员只能根据时间记录工单,而没有“思考,整合和质量重构”的工单,也没有针对这些工时的宽裕时间。
  3. 没有足够长的时间让任何人拥有该架构,以至于无法掌握它
  4. 不允许该人进行他们认为需要的更改

以这种方式查看它,很容易看到对敏捷与敏捷的某些解释实际上如何使您更快地走上这条路!

一种方法是为重构的每一位创建票证。问题在于,在开始处理较小的凭单之前,您常常没有意识到需要进行大量的重构,从而推迟了截止日期,并且凭单经过批准循环只会减慢一切。

另一种方法是计划冲刺仅使用团队容量的25-50%。然后,开发人员将他们的时间记录在实际的工单上(记录无需重构的时间)和重构时间(一周一张大工单,无批准循环,仅开发人员之间进行讨论)。如果没有重构,则可以从下周的冲刺中提取票证。随着项目基础代码的改进,您可以调整未来几周的百分比滑块。

因此,回答“我们在做错什么”,我想说的是您对方法论的信任超过了常识。您甚至要求“针对此问题的敏捷方法”。我想说点什么,然后考虑一下实际的问题。如果您然后真的想分拆各种宣言,试图破译最终的常识性方法是否确实以“敏捷”或“混乱”为幌子,那就一定要去:-)


-1

您没有做错任何事。这种方法论旨在以最快的速度向规范交付功能。

如果您确实有要实现的次要目标,则最好将其表示为“非功能性需求”或“完成的定义”。

例如,您可能有非功能性要求:

“所有新功能都必须用React编写”

“所有异步调用都必须实现加载微调器和错误处理”

您只需要让您的产品负责人(或同等学历)同意这些是值得做的事情,而不是因为开发人员喜欢它们而潜入其中。


“这种方法论旨在以最快的速度向规范提供功能。” -绝对不是Scrum的目标。您所说的方式尚不清楚这是否是您的意思。
Bryan Oakley '18

抱歉,我想这是关于在设计阶段和后期交付功能的问题?
伊万

不,不是。Scrum致力于与客户合作,以​​高度可见,迭代的方式交付高质量的软件。Scrum没有说要提供低质量的功能而不是进行适当的工程。
布莱恩·奥克利

2
如果您可以原谅我的批评,那么您似乎对Scrum到底是一个非常坚定的想法。但是,如果今天我查看指南和其他“官方”声明,一切似乎都令人望而却步。我认为您很难找到一个明确说明此事的声明
Ewan

1
@Erik他们认为这很混乱,因为他们想使用react。开发团队不能只决定自己重构所有内容。客户将拒绝为冲刺付款。
伊万
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.