为什么代码的“复制和粘贴”是危险的?

有时候,我的老板会向我们抱怨:

为什么我们需要这么长时间来实现一个function?

其实这个function已经在另外一个应用程序中实现过了,你只需要从那里复制粘贴代码即可。 成本应该很低。

这真的是一个很难的问题,因为从我的angular度来看,复制和粘贴代码并不是那么简单。

你有什么好的理由向你的非技术老板解释这个吗?

如果您在复制粘贴代码中发现错误,则需要在每个地方修复它,并希望您可以记住所有这些(这也适用于已更改的要求)。

如果你把逻辑放在一个地方,那么在需要时就可以更容易地进行更改(所以如果你决定应用程序需要更新,你只能在一个地方做)。

让你的老板读干的原则 (不要重复自己)。

您所描述的内容听起来像是图书馆的完美使用,您可以共享代码并将其保存在一个地方。

如果我打算在不久之后重新构build代码,我只会复制粘贴代码 – 确保后来我提取了通用代码,这样我就可以重复使用尽可能多的逻辑。 而不久之后,我的意思是几分钟后,而不是几天,几周。

通过构build库来分享代码,而不是使用复制和粘贴来复制代码会更好。

与重写相比,您仍然可以获得速度优势(查阅DRY),但只有一个地方可以维护代码。

显而易见的原因是,你为未来承担了“债务”:任何你需要在代码中做出的改变(不仅仅是错误修正,任何改变)现在要花两倍的代价,因为你必须更新两个地方 – 更有风险,因为你最终会忘记其中的一个。 换句话说,现在加速工作会使你的工作在未来更慢,这可能是很好的商业意识,但通常不是。

但更重要的原因是,“这是一样的”这个假设通常不是微妙的错误。 只要你的代码依赖于不言自明的假设是正确的,把它复制到另一个地方就会导致错误,除非这些假设也在新的地方。 因此,粘贴的代码从一开始就经常是错误的,而不是在下一次更改之后。

devise明智的复制代码当然是一场灾难,未来可能会导致很多问题。 但是你问为什么现在需要你很多的工作,答案是:因为它不只是复制和粘贴。

如果原始代码是为了被重用而编写的,作为一个相当独立的库,灵活性和客户端的使用 – 然后很好,但这不是复制粘贴,而是使用代码库。 真正的代码复制粘贴通常更像这样:

  • “当然,我已经有了这样的代码!”
  • “等等,这五个版本中的哪一个是我想用作源代码的那个?”
  • “呃,这些'util_func_023'函数做了什么?我没有logging它们吗?我现在需要哪个?
  • “哦,是的,这个代码使用代码库Y.猜猜我需要[ select一个:将所有的代码库Y复制到我的新项目中/花费一天时间从Code Base Y中parsing出我想要的一个函数/花费一个星期我想从代码库Y中获取一个函数]。
  • “我抄了一切,耶!
  • “为什么这不起作用?”
  • 这是您花费几小时/几天/几周来debugging与您想要的代码相似的代码的地方,而不是编写您真正想要的代码。

总之,现有的代码不能直接使用,充其量只能作为编写类似代码的一个很好的参考。 它当然不能完全解除,并期望在一个完全不同的系统中工作。 一般来说,这是一个安全的假设,即任何已经被编写和完成的代码应该尽可能less地被干扰 – 即使是一个副本而不是原来的代码。

如果你想将你的项目build立在复制粘贴的基础上,你必须以一种方式开始编码,这样可以方便地重复使用, 而不需要复制原始的代码并搞乱它。 这是值得的,如果这是你的老板所期待的,那么你们都需要确保这就是你devise和工作的方式。

复制和粘贴是一个等待发生的灾难。 您的老板应尽早评估运输的价格,以及最终用户破产码的价格。

如果您已经实现了这些function,并且需要复制并粘贴以重新使用这些function,则听起来您已经做了错误的事情。 你不能把这些function放在一个库中,这样你可以重复使用它们而不需要复制/粘贴?

干的原则(不要重复自己): 在维基百科干 。

“每一个知识都必须在一个系统中有一个单一的,明确的,权威的表示。”

其他链接 。

这听起来像你的非技术老板最糟糕的误解,是你的工作主要是打字。 他们认为通过消除打字可以节省大量的时间。

我认为你可以给这个人最好的教育就是指出你所做的那些没有打字的工作。 即使大部分的工作通常是在打字的同时,在你的脑海里,无形中发生的。

当然,消除打字将节省一些时间。 但是,那么更大,更没有打字,工作的一部分会变得更大,并且随时可以节省更多的时间。

你确定你的老板想知道DRY的原理,bug和其他技术?

当你的老板或公司低估了完成某个项目所需的时间时,你通常会听到这种评论。 并根据错误的估计签订了一份合同等。在大多数情况下程序员没有参与估计。

为什么会发生? 有时项目发起人的预算太less。 也许你正在使用软件自动化的业务stream程不值得你的团队努力。 在这种情况下,pipe理者通常会因为坏消息而closures。 项目一开始就有一厢情愿的想法。 然后pipe理者试图责怪程序员。 在你的情况下间接通过复制和粘贴。 在极端情况下,这被称为死亡游行 。

复制和粘贴代码通常会导致“ 巧合编程”

我认为“ 另一个应用程序 ”是关键在这里,如果其他应用程序已经testing和使用,它不应该被改为使用一个共同的库,因此你不能共享代码。

同一个应用程序中 ,“复制和粘贴”是不好的,但是在由不同团队开发的代码库或不同的发布周期之间,“复制和粘贴”是最好的select。

我曾为一家类似的公司工作。 作为一名实习生,我当时并不了解得更清楚,所以当我开始一个新项目时,我的老板也build议从其他地方粘贴代码。 那么,你可能会认为,整个软件是相当混乱的,直到当你试图修复一个错误时,出现了两个新的错误。

即使其他应用程序已经具备了您所需要的function,但是该function的代码可能不会适用于当前的应用程序,而无需进行重大改写。 这就像是一辆福特的发动机,并试图将其装入丰田。 一般来说,有一条经验法则,如果你要修改25%以上的代码,那么从头开始重写它会更好(更便宜)。

将有问题的代码提取到一个库中听起来令人信服,但这可能比听起来更困难,这取决于其他系统的构build方式。 例如,该function的代码可能很难提取,因为它以不洁的方式连接了很多其他的代码(例如通过访问大量的全局variables等)

告诉你的老板,每个variables名称的部分包含了旧项目的名称,现在你必须手动改变它们。 如果你的老板不知道(或者想知道)为什么复制/粘贴不好,他/她可能会相信:)

在您面前即时function的开发速度(特别是应用程序较小时)之间进行权衡,而随着应用程序的增长,还需要长期的维护成本。

复制和粘贴对于即时function来说是更快的,但是,随着应用程序规模的扩大,在修复错误和进行系统范围的更改以及在应用程序的不同组件之间维护工作stream程方面,您将付出沉重的代价。

这是企业主需要听到的说法。 这类似于维护车队的公认成本,但是,对于软件来说,软件架构的破碎方面一般是隐藏在业务方面的,只能被开发者看到。

他是对的,如果球队之前已经实现了类似的function,那么第二次重复它就会容易得多

但是,您应该可以解释每个应用程序是不同的。 仅仅因为你在一个房子里安装了一扇门,并不意味着你可以在另一个房子里安装另一扇门 – 由于经验(安装了#门),你将会更快,但是要得到你的设备还需要一段时间,安装门,确保它是铅垂的,并将其拧入框架。

是的,最大的问题是,它不只是复制和粘贴 – 它的副本,然后粘贴,然后稍作修改。

然后,当其中一个粘贴变体出现问题时,就会发生变化。 之后,另一个变体会被改变。

然后,你会发现,所有的变种都必须改变原来的副本有错误。 现在你已经完全搞砸了,因为所有的粘贴区域现在都不一样了。

你不知道吗,这种蹩脚的编码通常几乎完全没有意见。

对我来说,不同的是,当你有多个代码副本做同样的事情,你有什么是一堆代码。 当你只有一个代码做每一个特定的事情,那么你有一个系统。

一个系统的行为可以很容易地改变单点修改 – 改变一堆代码的行为需要一堆代码。

我喜欢系统,而不是一堆代码。

在我的公司,我们总是使用类和方法,并为他们制作技术文档。 我认为这是最好的做法,如果你可以使用你自己的svnsearch应用程序与良好的键find方法之前使用的类:)