使用敏捷方法时如何获得良好的设计?


15

我已经使用敏捷方法(SCRUM)大约三年了,我看到了它的某些优势,特别是在许多级别的短期反馈中(来自能够早期访问已实现功能的客户,来自可以测试功能的测试人员)。实施后,其他开发人员可以通过审查等方式就新代码提供非常早期的反馈)。

另一方面,我有两个悬而未决的问题,第一个我将尝试在这个问题中进行解释。

问题:难以获得良好的设计

我试图在代码混乱时立即进行重构,我会尽力编写单元测试(这确实有助于防止错误,尤其是重构时)。另一方面,以小增量开发一些复杂的功能,每天提交并在非结构化代码时不断重新思考代码,这使我无法产生出真正好的设计。

我最近采用的另一种方法可以生产出唯一经过精心设计的模块,方法是采用不同的方法:我分析了几天的问题(实际上,在我开始认真研究该问题之前,我已经将这个问题花了几个月的时间) ),为所有涉及的类及其之间的关系草拟了相当详细的设计,持续了两天,然后将自己锁在办公室,并通过不间断地工作了大约三周时间写下了整个代码。结果是我一段时间以来取得的最好的结果,很少有易于定位和修复的错误,并且设计非常清晰,自此以后就不需要进行任何相关更改。

因此,到目前为止,我发现预先了解要执行的操作的总体效果比开始以小增量编写代码要有效得多,以期在此过程中神奇地出现大效果。尽我最大的努力,小增量开发方法一直使我的设计变糟。

问题:有没有类似的经历?我是否以错误的方式应用SCRUM,或者如果我想以较小的增量进行开发并且最终仍然使用精心设计的软件,应该注意什么?还是应该在开始实际编码之前安排设计用户故事?至少对于比平均水平更复杂的功能,这是否被视为一种好的做法?

编辑-注意

我知道这样一个事实,即好的设计不是绝对的东西,本身没有价值,而是取决于上下文,因此,人们应该针对一种足以解决当前问题的设计。

例如,如果我必须实现一个简单的组件,即(1)必须尽快准备就绪,(2)仅使用一次,(3)不用,那么我不会在乎(过分)好的设计。由系统的其他部分(YAGNI)使用。

当组件(1)会被多次使用并且会在产品的几种不同版本中使用时,我确实会在乎良好的设计;(2)需要维护并随着时间的流逝而扩展;(3)取决于它,还有很多其他组件。


5
The only well-designed module I could produce recently I obtained by taking a different approach - 你是在自问自答。您仍然需要一些前期设计。您不能指望一个好的设计会因重构而简单地有机增长。那样行不通。
罗伯特·哈维

1
否。因为可能我没有正确应用SCRUM。
乔治

3
根本没有“正确累积”之类的东西。只有能够产生期望结果的过程。
罗伯特·哈维

1
这就是为什么它们被称为“准则”的原因:)无论如何,每天都要提交,要进行短时间(1周到1个月)的冲刺,而这样的规则在设计时根本不起作用。您仍然需要设计。
罗伯特·哈维

Answers:


13

另一方面,以较小的增量开发一些复杂的功能,每天提交并在非结构化代码时不断重新思考代码,这使我无法产生真正好的设计。

那不要那样做

并非所有内容都适合漂亮的敏捷框。通常情况下,产品会包含一些复杂的东西,这些东西无法耕种给个人,并且无法在冲刺中以任何理智的方式完成。强迫他们进入那个盒子只会造成麻烦。但是这些之间应该是很少的。如果您发现许多组件都是这样的,那么您的产品负责人就需要更好地分解(与您的团队合作)。我做得很好,就像您所做的一样:编写故事,设计故事,然后尽快将其付诸实践,期望会花费几周的时间。

在更一般的情况下,为了在Agile中获得良好的设计,我完成了三件事:

  • 实际进行设计 -我见过的很多地方都开始了冲刺,只是开始编写代码。这样您将获得糟糕的设计。敏捷不会改变计划-代码-测试-发布的开发过程,只是将其缩短为更精细的部分。在冲刺开始时,根据需要坐下来,然后实际设计解决方案。

  • 拥有一名架构师/负责人 -一旦您的项目足够大,您最终将需要多个Scrum团队来处理应用程序的不同部分。让某个人(或多个人,取决于应用程序的大小)的主要工作是从设计的角度了解所有团队的工作,这非常有用。他们可以回答问题,并指导团队进行更和谐的总体设计。我也已经看到,让每个Scrum团队都有一个领导,知道其他团队的大部分工作,并且非常有效。

  • 成为实用主义者 -我已经在上面提到了这一点。敏捷是一种工具,就像任何其他工具一样;它并不适用于所有问题。如果没有必要将其应用于某个组件,则不要将其应用于该组件。您的目标是交付良好的软件。不要忘记它。


3
+1(如果我有多于一票,则为+10!)“强迫他们进入该框只会造成麻烦”。
乔治

17

以很小的增量实现并最终得到结构良好的可维护代码是很有可能的。从理论上讲,这非常简单:如果您确保每次更改后代码的结构正确,那么它将始终保持结构良好。您的代码结构变得很糟糕,因为您应该在重构时继续添加代码。

无论您花多少时间进行设计,最终需求都会以某种无法预料的方式发生变化,并且您将不得不编写与原始设计不符的代码。然后,您将不得不进行增量更改。如果您有一套很好的单元测试,并且精通重构,那么您可以在满足新要求的同时保持结构良好的代码。


+1:好的。因此,当我认为有必要时,应该安排一个重构故事,并且在我没有足够好的设计之前不要添加任何新功能。这可能是我们在流程中所缺少的(除了IMO,我们正在开发的增量通常太小)。
乔治

2
实际上,您应该添加技术债务的故事并与产品负责人讨论何时对其采取实际行动,这就是技术债务的含义。

4
我见过的所有项目都通过创建“技术债务”故事或类似的故事将代码质量的责任交由产品所有者掌控,代码质量始终被低估,以至于严重损害了速度和士气。我相信团队是负责代码质量的实体。团队应该估算故事,以便有保留或减少技术债务的交付空间。
Buhb

4
不应发生“重构故事”或“技术债务故事”。决不。重构的成本是开发的一部分,并且不应作为单独的任务。事后,应该以小步连续而不是计划地进行。我知道这一点,我们的团队尝试了重构故事,这很糟糕。当您开始“即时”重构时,您会看到重构成为编码阶梯的一部分,而不是一个单独的任务。
Patkos Csaba

1
如果您认为该代码库将不能够方便地处理故事X没有显著重组/重写,那么这个重组应该是故事X的一部分,需要本次重组的工作应该估计故事X时,应考虑
Buhb

6

“精心设计”是主观的

什么是“精心设计的”对你意味着什么?给产品负责人?给客户?

“精心设计 ”的产品拥有者的目标是什么?客户的目标?还是只是你?

请问是什么原因,你认为“没有设计好”仍满足产品负责人的期望,使顾客高兴的?那是相当“精心设计的”

足够好,YAGNI

在大多数敏捷方法论中,没有什么是“精心设计的”,因为产品负责人认为故事是完整的,并且客户认为满足其要求的任何系统都是“精心设计的”

预计,开发商是专业人士,将务实地采用最佳做法,适当的设计和成语来实现的功能和故事。

如果您没有考虑到正确的时间做开发人员的问题,如果产品负责人在更短的时间内要求完成这些事情,那么这样做是他们的特权,并且您有责任对他们进行教育。技术债务故事形式的后果。

SCRUM

可以写下的敏捷方法论不是敏捷方法论。”-Jarrod Roberson

SCRUM被认为是管理软件产品总生命周期的工具框架。它不应该是一成不变的事情,而只是一个开始并希望有所改进的好地方。

我工作过的大多数商店都有所谓的Sprint ZERO,即Sprints,用于团队的高级成员草拟产品的总体架构或主题。

大于20的故事通常会被分解,直到实际上只有3-5点的故事为止。其中一个故事是:“作为一个团队,我们需要开会讨论我们将如何设计此功能,以便在分配的时间范围内,我们将承担尽可能少的技术债务。”

通常

总的来说,“精心设计”的系统足够好,并且遵循YAGNI。

敏捷,尤其是SCRUM作为敏捷的实现,更多地是关于如何对产品所有者/赞助商透明地生产产品。

这与技术设计/架构无关。它是关于如何交付满足客户需求和期望的软件的一种哲学。如果没有所谓的“设计精良”的零件,那么这本身并不是失败,因为它不是哲学的基本组成部分。


2
“精心设计”是产品所有者的目标:不是直接目标。间接地,是的:精心设计意味着易于调试和维护。我不得不花数周的时间才能在杂乱且设计不良的代码中找到严重的错误(使应用程序崩溃)。
乔治

3
真是令人沮丧的答案。基本上,它保证了平庸的软件像灰色的粘糊糊
罗伯特·哈维

@Giorgio不是目标,这是隐含的期望。

@RobertHarvey我知道您已经看过泥浆大球视频并阅读了这篇论文。这是现实生活,特别是SCRUM是对BBOM的认可,并通过接受熵作为过程的一部分并通过尝试对其进行记录(技术首次亮相)并放慢它的速度(重构)来将其包含在方法论中。是的,您应该从完全的BBOM /熵开始,但在现实生活中并非总是如此。

1
可以,但是您不能吃“暗示的期望”。那只是挥舞。 “因为我是专业人士,而且我知道自己在做什么,所以架构会很好。” (使用我最好的Bill Murray声音)是的,对。
罗伯特·哈维

3

我们已经与Scrum合作了几个月,我想分享一下有关您的问题的经验。

几个月前,我得到了很大的实施空间。我已经准备好所有规范,因此必须相应地实现新功能。任务大约需要5-6周(据我估计)。我花了第一周的时间只从事设计。任务有点复杂:正如我从规范中得出的那样,有一个主要对象具有15个不同的状态,UI对于每个状态都具有不同的行为。

我设计了整个工作流程,然后设计了数据库结构和类。

我的情况没有其他方法。如果我立即投入编码,那么最终我将陷入一团糟-几乎无法维护,并且极难进行任何进一步的更改。但是更改是在接下来的2周内完成的,因此我不得不重新编写代码。通过最初的深思熟虑的设计,现在这很容易。这节省了我们的时间,金钱和神经。

经过这一经验,我绝对确定在开始时就值得做一个可接受的设计,而不是希望奇迹般地在最后得到它。


1
+1:非常有趣的答案。敏捷的支持者会告诉您,您应该将6周的故事分解为较小的故事。曾经给过我类似的建议,我回答说我的六个为期1周的故事彼此之间会有很多依赖性:因为即使我更改了工作计划,也无法更改问题领域。我对此没有任何答案:敏捷通常会假设您可以分解一些小的独立故事,但在现实世界中并非总是如此。
Giorgio

1

后视是20-20。如果您在项目开始时就掌握了信息,可以弄清整个过程,然后在几周内编写代码,那么建议您这样做。

您没有对获得的所有见解,尝试过的和失败的/必须改变的方法以及客户/用户提供需求的能力增加给予足够的信任。

为什么任何拥有成功的瀑布项目历史的人都转向敏捷方法?


“为什么拥有成功的瀑布项目历史的人会转向敏捷方法?”:很好的观察(+1)。我认为在瀑布式和敏捷式之间进行选择应该与一个项目的类型有关:对于需求定义不明确的项目,需要频繁的原型并且原型可能成为最终产品的项目,敏捷性可能是合适的。对于要求更稳定且鲁棒性和稳定性更重要的项目,瀑布(或某些变化)可能是更好的选择。
乔治

0

在开始项目之前,您始终需要了解最终目标应该是什么,打算实现什么功能以及何时实现。将故事作为原子任务进行工作会带来麻烦。您需要牢记未来的需求。


安排设计用户案例是一种好习惯吗?
乔治

@Giorgio:这可能是不必要的,但是在项目开始之前,产品负责人至少应向其团队概述客户对项目的期望,并说明如何分解项目。
詹姆斯

1
如果有人反对,请给出原因
詹姆斯

拒绝投票的人很少花时间解释为什么拒绝投票。我觉得这很烦人。
Giorgio
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.