DRY是软件项目管理的敌人吗?


83

DRY是软件开发中最基本且被广泛接受的原则之一(请不要重复自己)。同样清楚的是,大多数软件项目都需要某种管理。

现在有哪些易于管理的任务(估算,计划,控制)?正确的重复性任务,正是按照DRY应该避免的任务。

因此,从项目管理的角度来看,最好通过将现有代码复制100次并根据需要对每个副本进行一些较小的改动来解决任务。在任何时候,您都确切知道您已经完成了多少工作,还剩下多少。所有的经理都会爱你。

相反,如果您应用DRY原理并尝试找到某种或多或少消除重复代码的抽象,则情况有所不同。通常情况下有很多可能性,您必须做出决定,进行研究,发挥创造力。您可能会在较短的时间内提出更好的解决方案,但是您也可能会失败。大多数时候,您无法真正说出还剩下多少工作。您是项目经理的噩梦。

我当然在夸张,但显然存在两难选择。我的问题是:决定开发人员是否过度使用DRY的标准是什么?我们如何找到一个妥协的解决方案?还是有一种方法可以完全克服这一难题,而不仅仅是找到折衷方案?

注意:此问题基于与我上一个主题相同的思想,即软件开发中的日常工作量及其对估计的影响,但我认为这使我的观点更加清楚,非常抱歉重复我的一遍:)。


96
让我们知道您需要在所有这100个复制粘贴实例中进行查找,更改和测试时,项目管理人员的感受。并且不要忘记花额外的时间弄清楚为什么它最终会损坏,因为实际上只有98个被更改。
Blrfl

16
另一方面,@ Blrfl会在过早清除一个好的抽象之前过早地干燥代码,这也确实会损害生产力,因为共享的抽象是一个共享的依赖项。顺便说一句,我并没有不同意,只是指出肯定有一个平衡。
GoatInTheMachine

16
防止DRY失控的原理是YAGNI(您将不需要它)原理。
菲利普

88
没有两难选择。如果项目经理由于您容易估计而希望您做很多多余的手工工作,那么显而易见的解决方案是解雇项目经理。
JacquesB

10
如果您重复自己,那么您仍然必须完成所有其他难以估计的工作,以及一些额外的毫无意义的工作。那么,这对项目有何帮助?
immibis

Answers:


134

您似乎假设项目管理的主要目标是产生准确的估算。不是这种情况。项目管理的主要目标与开发人员的相同:为产品所有者创造价值。

从理论上讲,使用很多缓慢的手动流程而不是自动化的产品可能更容易估算(尽管我对此表示怀疑),但是它不能为客户提供物有所值的东西,因此,这仅仅是糟糕的项目管理。没有两难选择。

众所周知,对软件项目的估算很困难,并且已经编写了许多书籍,并且已经开发了各种方法来对其进行管理。

如果PM 的唯一目的是产生精确的估计值,那么这将很容易。只需将估算值提高到10倍,然后让开发人员尽早完成其余的游戏即可。实际上,这比您建议使用复制粘贴工作来节省时间更好,因为玩游戏不会降低产品的可维护性。

但实际上,产品负责人希望获得有用的估算,希望尽快,廉价地交付高质量的产品。这些是PM必须导航的实际约束。

无论如何,我反对您的假设,即重复的手工工作比自动化更可预测。所有经验表明,重复的手工工作容易出错。如果在复制粘贴的代码中发现错误,该怎么办?突然,修复错误的成本乘以重复的次数,这使得不确定性激增。


21
我完全同意您在这里的主张,但是我认为需要指出的是,有很多糟糕的项目经理确实比速度或质量更偏向于可预测性。大多数没有接受过项目管理培训的人都会从他们所看到的东西中学到关于它的知识,而我的经验是,能够以一种冷静理性的方式处理不确定性的项目经理很少而且相差甚远。
JimmyJames

5
@FrankPuffer我去过那里。这需要多长时间?这里的一种选择是提供范围。仔细阅读PERT的三点估计值,因为他们应该已经知道了。完成百分比?这是最烦人的。尝试忽略它,但是如果您不记得它是百分比时间,则不是代码行百分比或其他。他们真正想知道的是何时完成?尽早为每个任务提供保守的预测,并在进行时不断完善。等到最后一分钟说出更多的时间,会让人们发疯。
JimmyJames

11
这需要多长时间?我有60%的把握可以用x完成它,但是有10%的机会会花费五倍的时间。
大卫,

18
@David:这可能会使PM疯狂,因为他从经验中知道这种10%的机会实际发生80%的时间:)
Frank Puffer

7
现实是,许多地方都希望将项目追踪到地面,然后意外地成功。PM经常因具有准确的预测而获得奖励,因此他们有不正当的动机。这是委托代理问题
雪橇

39

您是对的-复制粘贴的效果很好,当您的任务是生成程序时,DRY没有意义,因为将来不再需要为其维护复制或复制的模板或副本。当这两个软件组件的生命周期完全不同时,通过将公共代码重构为公共库(本身正处于繁重的开发过程中)将它们耦合在一起,确实会对工作产生不可预期的影响。另一方面,在一个程序或程序系统中复制代码段时,所有这些部分通常具有相同的生命周期。我将在下面说明这对DRY和项目管理的意义。

认真地讲,那里有很多这样的程序:例如,计算机游戏行业生产了很多程序,这些程序最多只能在几个月或一年的短时间内得到维护,而当该时间结束时,就会粘贴粘贴从以前的游戏(其中维护期已被缩短)中的旧代码过渡到新游戏的代码库中就可以了,并且可以加快处理速度。

不幸的是,过去几年我必须处理的大多数程序的生命周期都与此截然不同。到达我的需求或错误修复请求的98%是变更请求用于现有程序。而且,每当您需要更改现有软件中的某些内容时,当您的测试和调试工作量很少时,“项目管理”或计划就可以达到最佳效果-如果您在一处进行更改,但由于复制而导致的情况并非如此粘贴的业务逻辑,您很容易忘记,您还需要在代码库中更改其他十二个位置。即使您设法找到所有这些地方,更改所有地方(并测试更改)的时间也可能要高得多,就好像您只有一个地方要更改一样。因此,即使您可以对更改进行准确的估算,其成本也比所需的成本高十倍,很容易与项目预算相抵触。

TLDR-每当您开发一个程序时,就不必对原件或副本进行错误修正和维护,也可以不承担责任。但是,如果您,您的团队或您的公司有责任或可能要负责任,请尽可能使用DRY。

作为附录,让我通过一个实际的例子来解释“错误修复和维护”的含义,以及这如何导致计划中的不可预测性,尤其是在一个产品内部。我确实已经看到这类事情是现实发生的,可能不是100个实例,但是当您只有一个重复的实例时,问题甚至可能开始。

任务:为一个应用程序创建100个不同的报告,每个报告看起来非常相似,报告之间存在一些需求差异,逻辑有所不同,但总的来说,差异并不大。

完成此任务的开发人员将创建第一个任务(假设需要3天),由于质量检查和客户检查完成了一些更改或较小的错误修复之后,它似乎运行良好。然后,他开始通过复制粘贴并修改整个内容,然后创建下一个报表来创建下一个报表,对于每个新报表,他平均需要大约1天。乍一看非常可预测...

现在,在“准备好” 100个报告之后,该程序开始投入实际生产,并且出现了一些问题,这些问题在质量检查过程中被忽略了。也许存在性能问题,也许报告定期崩溃,也许其他事情无法按预期进行。现在,当应用了DRY原理时,只需在一个位置更改代码库就可以解决90%的问题。但是由于采用了复制粘贴方法,因此该问题必须解决100次而不是一次。而且由于已经从一个报告更改为另一个报告,因此开发人员无法快速将第一个报告的修复程序复制粘贴到其他99个报告。他必须查看所有100个报告,阅读它们,并将更改转换为已修改的报告。报告,测试并可能分别调试每个。对于下午 这开始变得非常困难-他当然可以花一些时间进行“常规”错误修复(比如说3个小时),然后将其乘以100,但是实际上,这很可能是错误的估计,某些修复可能是比别人更容易做,别人可能会更难。即使这个估计是正确的,调试成本也要比其所需的成本高100倍,这将使您的公司付出大量金钱。

下一次,当客户要求更改所有这些报告中公司徽标的颜色,使页面大小可配置或通过其他以类似方式影响所有报告的新要求时,也会发生同样的情况。因此,如果发生这种情况,您可以估算成本,并向客户收取代码干燥后必须支付的价格的100倍。但是,尝试几次,然后客户将取消该项目,因为他可能不愿支付您高昂的开发成本。也许那时有人会问为什么会发生这种情况,然后用手指指着决定进行此复制粘贴编程的人。

我的观点是:当您为他人开发软件时,至少在短时间内,您总是有责任使事情正常运行,修复错误,使程序适应不断变化的需求等。即使在未开发的项目中,这些零件的总和远远超过了最初计划的开发工作。尤其是当所有复制粘贴的代码都放在一个产品中时,所有部分的责任期限是相同的,这与您从已失效的项目中复制粘贴了一些较旧的代码而不再是这种情况完全不同正在积极维护中。


4
可能是一个好的答案,但与其他好的答案相比太冗长了。
文斯·奥沙利文

4
当“将来不必维护或升级副本”时,您可以忽略DRY,但是永远不会再使用的代码经常反而会再次被使用。
安迪·莱斯特

“复制粘贴效果很好...”-不同意!即使该程序是一次性的,并且保证永远不会超出初始发行版,但复制粘贴代码仍然使它的工作量更大,并且有可能修复在程序初始版本开发期间发现的错误。除非您从未犯错,否则您就是上帝。
JacquesB

1
@JacquesB:您应该更仔细地阅读我的答案,我没有写出不同的东西。
布朗

计算机编程与使用装配线制造相同的机器只是有所不同。嗯 谁会打它呢?也许我们应该让程序员担任PM。但是,那么我们将需要程序员作为管理者。程序员作为股东。程序员作为客户...开枪,只教每个人如何编程和完成编程。(换句话说:非专家永远不会理解专家所熟知的沧桑。)

19

因此,从项目管理的角度来看,最好通过将现有代码复制100次并根据需要对每个副本进行一些较小的改动来解决任务。在任何时候,您都确切知道您已经完成了多少工作,还剩下多少。所有的经理都会爱你。

您的基本断言不正确。

使软件其他行业不同的是,您每天都在制作新的东西。毕竟,没有客户会付钱给建造别人已经制造的东西。项目经理可能喜欢可预测性,但他们的老板喜欢价值。如果您只是复制粘贴的代码而只是稍有变化,那么您就不会为公司提供太多价值。

最终,公司将认识到,通过聘请优秀的程序员,他们可以在短时间内完成相同的工作。如果他们不这样做,他们的竞争对手也会这样做。


2
我认为大多数工程专业都是关于“每天创造新事物”的
BlueRaja-Danny Pflughoeft

12
@ BlueRaja-DannyPflughoeft:不是。作为电子/电气工程师,我可以证明大多数大型工程专业(那些需要调试的项目,例如造船和发电厂)都是要确保人们经过尝试和测试的工作能够正确完成。这就是企业认为的“工程”。创造新事物是“ R&D”
slebetman's Aug17

3
@slebetman也许您只是没有注意到您的管理层正在做的所有工作。即使您一次又一次地做同样的事情,环境也会每次都在变化-您没有电厂的模板可以直接交付给客户并完成,您需要进行测量,弄清楚如何为工厂提供原料,并带回产品,管理施工中的所有原料,并解决供应问题和工作短缺以及百万其他问题。它看起来像模板工作(因为许多软件努力做),但它真的不是。
a安

1
@Luaan:是的,但是这些都没有带来新的东西。他们都在“做我们知道怎么做的事情”。软件开发是不同的。主要是因为在软件中,与物理工程项目不同,我们倾向于将已经知道如何做的事情封装在库中,因此我们不必手动“进行测量”等。我们只需为此导入一个库并使用它。
slebetman'8/08/

2
@slebetman几乎所有编写的软件都是“我们知道该怎么做”。图书馆生活在随时变化的环境中。而且您没有整个库的100%知识和经验,以及该库的所有依赖项以及您拥有的其他依赖项,并且有许多奇怪的系统和硬件配置,它们只是拒绝以合理的系统应有的方式工作工作。封装虽然很棒,但是它仍然很昂贵,需要大量的测量工作。而且工程已经封装太-预制块,集成电路等
Luaan

12

剪切和粘贴编程最终导致废弃的软件。我是一家系统的承包商,该系统用于从一家大型电话公司订购有线服务。由于所有测试都是手动进行的,因此他们不想更改任何工作代码,因此该系统被反复粘贴。最小的增强可能会导致数百行代码的新副本。最初,该应用程序被编写为处理多达十二个物理行的帐户。当然,此限制是在代码中的数百个位置中进行的。大约四年后,业务部门询问团队如何处理较大的帐户。他们估计约有1800万美元。那时,该项目已移交给了海上团队,以减少维护工作。现有团队全部解雇。

认为这种方式的组织正被技术更好的公司所压倒。


它认为这是更好的大脑,而不是更好的技术。技术来自大脑,对吗?无论“想更聪明,不要更难”,发生了什么?

10

在这里适用的一个常被遗忘的格言是3的规则。这说明,一次复制代码是可以的,但除此之外,还应将其替换为通用代码。

3 似乎是一个任意数字,但常见的情况是在应用程序和数据库中重复数据和逻辑。经常引用的一个示例是数据库中有一个查询表和一个枚举客户端。范式的差异不允许将其容易地存储在单个位置,因此信息经常出现在两个位置。

拥有DRY代码固然很好,但有时业务逻辑会规定一个异常,因此您必须从以前的通用源创建两个或更多位代码。

那么该怎么办?用于表示当前状态的代码(毕竟是YAGNI)。虽然应该编写代码以便于修改,但是编写一些不必要的东西只是浪费金钱。


6
请注意,这确实意味着您应该评论已复制了代码(在两个地方),这样您就知道是否要再次复制它,不应该!
马克·赫德

3
我是在两个类需要相同方法但几乎没有关联的情况下完成此操作的-有点像远亲。我不得不将依赖项添加到几乎一打类中,以使它们实际共享代码。因此,我确实喜欢Mark的建议-复制粘贴了该方法,还留下了一个明显的大注释,指出了该方法的其他位置。
尤特纳格'16

@MarkHurd Yep-好点...
Robbie Dee

8

在您的问题中,您仅列出了项目管理的三个功能-估计,进度和控制。项目管理是关于在项目约束内实现目标。在软件项目中,用于实现项目约束内目标的方法与许多其他类型的项目不同。例如,您希望制造过程具有高度可重复性且易于理解。但是,软件开发主要是知识工作-这是非常规的,需要思考,而不要遵循严格的指示和程序。用于启动,计划,执行,监视和控制以及关闭软件项目的技术将需要考虑需要在软件项目上完成的工作类型,特别是无法完成的非常规工作具体说明和程序。

我认为另一个问题是您正在采用DRY(一种与信息重复相关的概念),并试图将其应用于管理任务。DRY只是说您应该只拥有一种权威的信息表示形式。项目经理应该接受这一点,因为这意味着每个人都将知道该去哪里获取信息,交流变更将变得容易,并且变更可以得到很好的控制和管理。通过可重复使用的组件,DRY有助于降低长期成本,有助于维护长期进度并提高质量-这是项目管理三角的三大要素。要使DRY变得有效,需要花费一些时间和金钱,但是项目经理的工作是在时间,成本,进度和质量之间进行权衡。


当然,软件开发是知识工作。实际上,严格来讲,我什至不认为我的第一个示例(复制/粘贴)是软件开发。尽管如此,管理这类工作要困难得多,因此,即使PM具有开发背景并且知道所有这些,但作为PM的角色,PM往往会忽略它。(我并不是说这是一件好事,这只是我多次观察到的事情。我也不认为这些PM是愚蠢的或无能的。这更像是有时迫使他们采取这种行动的角色。 )
Frank Puffer

3
@FrankPuffer我不同意项目经理的角色会迫使人们做出特定的决定。它更可能是教育或组织力量。据我了解,大多数项目管理教育都比软件项目管理技术着重于更传统的项目管理技术(可能是因为它们更普遍地适用于更多项目)。这可能会渗入期望的组织中,而不会考虑其他用于管理知识工作项目的技术,例如软件开发。
Thomas Owens

2
@FrankPuffer确保它更难,但是它提供了更多的价值。如果老板的老板足够聪明,他将摆脱试图“使事情变得更轻松”的经理,并找到可以实际完成工作的人。不要误会我的意思,如果让事情变得更容易提供价值,那就去追求价值-但是按照您的描述,这几乎肯定会损害最终价值。
a安

4

编写新代码只是任务的一小部分

您的建议将使估算最初编写新代码的部分变得更加容易。但是,对于实际上带来任何新事物(无论是全新系统,增加功能还是更改功能)而言,这样做是不够的,而且只是其中的一部分工作-文献中的估计表明实际上部分大约占总工作量的20%-40%。

因此,大部分工作(包括使您的初始开发适应实际需求,集成,测试,重写,重新测试)变得不容易估计;恰恰相反,有意避免使用DRY会使零件变得更大,更难并且估计值更加可变-可能不会发生需要更改所有克隆部分的bug或需要更改的情况,但是如果这样做,则您的估计值就不会发生将是完全错误的。

通过提高一小部分工作的估计质量,您不会获得更好的估计,但是在大部分工作中却会变得更糟;因此,这并不是真正的权衡取舍,而是双输的情况,在这种情况下,您的生产率会下降,但估算值也会下降。


那是个很好的观点。但是,DRY或类似原理也适用于其他任务,例如测试或集成。大多数事情可以通过机械的方式完成,无需过多思考或以更智能的方式完成。智能解决方案通常要快得多,但存在失败的风险。另外,在获得任何结果之前,您必须付出大量的工作。
Frank Puffer

没有“失败的风险”,没有确定的失败。一切都会迟早失败。您只是在选择灵车的价格和驾驶速度。

4

DRY很有用,但也被高估了。有些人可能把它做得太远了。许多开发人员没有意识到的是,只要您实现DRY以将相同的方法用于两个(略有)不同的目的,就会在不同的用途之间引入一种非常紧密的联系。现在,每次更改第一个用例的代码时,还必须检查它是否使第二个用例退步。如果这些是广泛独立的用例,则是否应该紧密耦合非常令人怀疑-它们可能不应该如此。

当通常使用较小的原子方法来复制某些代码时,DRY的过度使用还可能导致上帝方法复杂化,以处理它们所处的所有不同用例。

但是,我建议这个问题在项目管理级别上并没有真正的意义。一个项目经理真的不想让自己关注这一级别的实施细节。如果是的话,那可能是微观管理。真的...... 怎么东西都实行的是开发者和技术领先的更多的责任。项目管理是更关心的是什么,得到执行和

编辑:根据评论,我确实同意,但是,只要可以更轻松地估算开发时间,避免DRY有时可以减少不确定性。但是,我认为,与以下更为紧迫的问题相比,这是一个无关紧要的问题:(1)满足业务要求需要多长时间;(2)在此过程中承担了哪些技术债务;(3)承担总成本的风险做出的架构选择的所有权-在很多情况下是否进行DRY处理是一种设计选择,应更多地基于对这些因素的风险/回报,而不是是否较容易为项目经理提供更准确的信息。


当然,项目经理不应处理实施细节。那不是我的意思。我的观点是,根据开发人员实施某些事情的方式,他或多或少能够提供项目管理所需的信息。
Frank Puffer

为了能够更好地报告产品,损坏/约束产品或增加技术债务对我来说没有任何意义。报告的值一定要比质量工作的值低几个数量级。但是YMMV
布拉德·托马斯

也许程序员应该比经理多付几个数量级的薪水?

2

我认为您误会了DRY。

我们来看一个例子:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

public Class B
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

public Class C : A
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

通过用C代替B类,我们遵循了DRY原理并减少了代码重复。但是我们并没有增加项目的未知数或风险(除非您之前从未做过继承)。

我认为谈论DRY时的意思更像是设计任务。即:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

!!!新要求!一些客户需要能够增加双打!

// Use class B for new clients!!
public Class B
{
    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

public Class A // Version 2
{
    public int Multiply(int x, int y)
    {
        return Multiply(x as double, y as double);
    }

    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

在这里(假设它可行),我们设计了一种解决方案,该解决方案可以满足旧的和新的要求,本质上是尝试为现实生活中的问题或业务规则创建数学模型。在现实生活中,我们正在建模的系统显然要复杂得多,我们的模型无法完全拟合,边缘情况和意外结果将需要时间来查找和纠正。

那么,在这种情况下,我们应该采用B还是A版本2?

  • B将更具体地针对实际请求的更改,且副作用更少,并且更容易估算和更快地执行。

  • 第2版​​将减少总代码量,成为更优雅的解决方案

我再次要说,这取决于规范和要求的质量。

如果我们有涵盖边缘情况和向后兼容性的非常清晰的规范,则可以确信我们对系统的了解足够深,可以重构模型而不会产生错误。

如果我们有一个针对单个客户的紧急请求,而唯一的要求是该客户的行为发生变化而无需考虑整个系统;然后通过重构A“改善”模型会带来很大的风险。由于设计和测试解决方案需要额外的未知时间,因此打破了其他客户或超过了最后期限。


7
我不同意 继承不是您一次要掌握的事情。有很多陷阱。有一些原因为什么应该优先选择组成而不是继承。因此,我们必须做出一个决定:继承?组成?还有吗 在现实世界中,此决定可能会很困难。在第二个示例中,还有很多选择。泛型/模板呢?也许使用lambda的某些功能性方法?再说一遍:许多可能性都有各自的具体含义。
Frank Puffer

4
关键是在第一个示例中,您可以通过任何方法从字面上删除重复的代码。但完全相同的代码会以两种方式执行。因此,功能变更为零。在第二个示例中,您将方法更改为希望功能实用但实际上是不同代码的方法
Ewan,

1
我当时的情况是您的“紧急请求”成为常态。我工作的公司为许多不同的客户创建了定制的数据系统。最初,他们使用Cobol创建了一个系统,然后将其复制给下一个客户,依此类推,直到有100个客户。现在,他们有一份工作要尝试进行系统的改进和更新。我正在一个可以使用一组源代码复制大多数这些系统行为的系统上,但自定义项存储在配置数据中。我们无法做任何事情,并且无法添加某些内容。

1

逐段

DRY是软件开发中最基本且被广泛接受的原则之一(请不要重复自己)。同样清楚的是,大多数软件项目都需要某种管理。

正确。

现在有哪些易于管理的任务(估算,计划,控制)?正确的重复性任务,正是按照DRY应该避免的任务。

重复性任务应是自动化的,强制性的。当手工制作时,它们很无聊,容易出错。

因此,从项目管理的角度来看,最好通过将现有代码复制100次并根据需要对每个副本进行一些较小的改动来解决任务。在任何时候,您都确切知道您已经完成了多少工作,还剩下多少。所有的经理都会爱你。

我认为您可以使用“配置”更改“适应”一词。考虑一下您应该在这段代码中复制一个错误。在特定条件下出现的错误。如果它不是在原始来源中固定的,而是被复制的,那么会有很多地方需要固定。这可能很糟糕,但随后有人必须:

  • 首先在原始源代码中修复代码;
  • 在其他地方修复代码;
  • 确保所有这些地方。当您对经理说必须这样做时,他可能至少会讨厌某人。

相反,如果应用DRY原理并尝试找到某种或多或少消除重复代码的抽象,则情况有所不同。通常情况下有很多可能性,您必须做出决定,进行研究,发挥创造力。您可能会在较短的时间内提出更好的解决方案,但是您也可能会失败。大多数时候,您无法真正说出还剩下多少工作。您是项目经理的噩梦。

删除重复项将导致单点故障。如果出现故障,您可以肯定会在哪里发生。SOLID和设计模式可帮助您准确解决该问题。期限太短往往会引起程序样式“编码”。为了创建可重用的项目,在一个项目中投入了更多的时间,这意味着在重用该功能时,在下一个项目中应该花费最少的时间,但是首先应该对其进行配置

我当然在夸张,但显然存在两难选择。我的问题是:决定开发人员是否过度使用DRY的标准是什么?我们如何找到一个妥协的解决方案?还是有一种方法可以完全克服这一难题,而不仅仅是找到折衷方案?

许多人指出这里没有难题。是的,没有。

如果您具有从未尝试过的高度实验性的东西,那么就不会有难题。否则,如果您需要再次执行某些操作,例如新的预订系统,则已经有了抽象,这取决于您的需求。

我认为难题是-如果不太可能要求我们在功能中实现某些功能。在要求时实施一些措施。没有人需要一个不会被使用的庞大基础架构。


现在就以简单,快速的方式实施某些操作,因为这是必需的。后来,当需要复杂的方法时,原始的努力是徒劳的,必须重新开始。经理不喜欢这样。就像您说的那样,“如果现在我们需要向东方行驶,那么花在西部的时间是没有用的。” 但是第一次走遍世界,这样我们就可以一直向东走,这也是浪费时间。

1

这根本不是为了将来的重用而设计,也不是关于YAGNI原则。它是关于在当前工作包中重复代码。

绝对是关于设计的。也许本质上不会重复使用,但是仍然可以进行设计。

有什么标准来确定开发人员是否过度使用DRY?

经验和您现有的环境/状况。对于给定的问题,当您尝试更大程度的DRYness时,您会强烈理解Prado原则。然后突然有了管理方面的考虑。时间,目标,客户,长期代码管理(有人称技术欠债)等将为您制定攻击计划。

我们如何找到一个妥协的解决方案?

嗯...设计吗?重构是设计,理应如此。DRYing的范围很容易像超新星一样从循环,方法到类扩展。去过也做过。但是直到您研究了问题,您才能真正知道-这就是设计。

怎么可能不是设计问题?您必须比手头立即复制的代码更广泛地考虑问题。无论是现有代码还是空白表,这都是设计活动。无论是“提取方法”还是创建新的类和模块。

结语

...所提到的问题及其答案不涉及项目管理方面。

典型的管理,忽略了设计时间。理想情况下,我们将在编码之前设计出多余的重复性。相反,管理层认为开发(和错误修复)只是一个奥林匹克运动会-编码-实际上是十项全能。他们测量到1/1000秒,因为他们认为这都是模拟的。

相反,如果您应用DRY原理并尝试找到某种或多或少消除重复代码的抽象,则情况有所不同。

我有这样的经验:“我花了两天时间来编写此行(GUI表单),花了两个小时来编写其余的表单。” 我的意思是,我花了一些时间来确定可重用的类-DRY是自然的副作用-GUI表单行以及其他一些内容。一旦调试,就可以在整个表格中单独或组合使用这些表格,而现在这些表格可以非常快速地进行编码,尽管建立起来很复杂,但是测试却异常快捷。而且它也以极低的错误率通过了正式测试。

大多数时候,您无法真正说出还剩下多少工作。您是项目经理的噩梦。

我也不知道,但是我有信心前期的设计工作会有所回报。我们都这么说,但管理层尤其不信任它。管理层本以为我在搞砸。“两天后,您甚至还没有2%的代码被编码!”

在一种情况下,当管理层说“您在设计上花费了太多时间,开始前进”时,我们坚持不懈。同事们说“这门课太多了”。好吧,一个不那么复杂的子项目原本应该花费大约1个月的时间(我以为可以猜测),但是花费了5个月的时间。其中3个月处于测试/修复状态,因为它就是这样的POS。“但是我们没有时间设计!”。他们实际上是这么说的。

我的问题是:决定开发人员是否过度使用DRY的标准是什么?我们如何找到一个妥协的解决方案?还是有一种方法可以完全克服这一难题,而不仅仅是找到折衷方案?

向管理层展示其运作方式。捕获一些数据。与其他工作进行比较,尤其是您的同事急于完成工作的同事。那堆失败似乎总是输掉比赛,陷入测试,然后在发布后又回来修复更多的错误。


“用千分尺测量,用粉笔标记,用斧头切割。”
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.