如何修复复制/粘贴模式?


16

在我工作的地方,人们(顾问)感到迫切需要尽快发布功能。因此,不必花太多时间去思考如何正确地做事,或者因为他们不想破坏任何东西,而是从不同的模块复制并修改代码。

要防止这种情况并不容易,因为代码库对整个公司都是开放的。很多人为此工作。

既然现在已经一团糟,那么在不破坏太多冗余的情况下删除这些冗余的最佳方法是什么?


3
最令人讨厌的是,当代码从某个站点被复制/粘贴后,甚至注释都没有被删除。因此,您可以找到:“ //感谢卡洛” ...当您将其指向他们时,他们只是笑着说:“离开!))”。那不是专业和悲伤!!!
CoffeeCode 2011年

2
它不仅是顾问
AndersK,2011年

Answers:


14

答案的一部分是重构

首先,开始编写单元测试,以确保您不会因更改而意外破坏任何内容。然后开始改进设计,逐步删除重复项等,在每个步骤之后运行单元测试,在任何测试失败的情况下解决任何问题,或者在遇到无法轻松解决的更大问题时立即恢复。

另一部分是教育

必须教导人们不要留下错误的代码。这无疑是一场长期的战斗,因为习惯和思维过程很难改变(有时甚至是不可能)。但是,如果没有它,您将继续获得大量的错误代码,以进行重构。

您可以选择进行组代码审查以打开有关好的和坏的编码习惯的讨论,并传播前者的优点。仅仅说“您必须(不要)编写这样的代码”是不够的,您需要用逻辑和事实来说服人们。就像“如果该方法在代码库中重复了 n 次,您认为如果在该方法中发现错误,该错误将在方法代码的每个副本中得到修复,那您有什么机会呢?”

您的公司可能还需要修改顾问的激励和接受标准 -如果他们可以摆脱编写草率的代码,他们肯定会继续选择更简单的方法。如果公司在长期可维护性方面一直看重“快速交付”,那么什么都不会改变:-(因此,您可能还需要与管理层讨论。让他们理解的一种方法是:重构意味着保持代码干净,容易了解和维护。省略重构就像积累信用卡上的债务。您可以暂时摆脱它,但是如果您没有积极地控制自己的购买习惯和债务,那么一天不可避免地会崩溃。在软件项目的生命周期中,破产是指项目变得难以维护:从头开始重写它比在现有代码库中添加新功能要容易。或者用户对低劣的支持和功能感到厌倦,以至于他们只是转向竞争者。


4
“首先,开始编写单元测试,以确保您不会因更改而意外破坏任何内容。” 哇,在那里刹车。我真的不喜欢SE网站上的每个人都这么冷淡地在回答中抛出这句话。这是非常难以弄清楚,是谁建议它做出来是用户不那么随便的99%。

@Sergio Tapia-是的,但是没有它就无法重构。欢迎来到现实,大约在2011
。– Scott Whitlock

1
@Sergio,如果您表示很难对遗留代码进行单元测试,那么我完全同意。我很高兴将引用的句子扩展为“首先,您应该开始编写单元测试的艰巨而艰巨的任务 ……” :-)但是,如果您是说由于单元测试很困难,那么您应该尽量避免我非常不同意(基于实践经验,而不是理论)。维护遗留代码没有皇家之路。
彼得Török

9

作为@Peter所说的教育的一部分,您可以引入像PMD这样的复制粘贴检测器,并将其用作构建周期的一部分,以帮助强制执行这部分编码标准。

确保您的项目编码标准涵盖了这种模式,以便您有一个开始讨论的基线。


1
我喜欢这个,很好!
ozz 2011年

是否有可能要求遵守承包商合同中的编码标准?
Armand

1
@Alison您可以要求遵循自己喜欢的任何事物,只要您事先声明就不会有问题。作为承包商,我坚持我所工作的公司的发展要求,其中之一就是遵守其编码标准。在提交到主干之前检查代码也可以帮助解决这一问题
DBlackborough

谢谢,在您发表文章后,我还找到了适用于Python / Java的clonedigger.sourceforge.net
LennyProgrammers

@ G3D很有道理;您喜欢制定一个编码标准吗?我将代码审查作为一种接受形式的问题是,作为承包商,我担心代码可能由于任意原因(例如政治或预算变更)而被拒绝
Armand

8

人们(顾问)感到迫切需要尽快发布功能

您没有技术问题,有社会问题。确实,您有管理上的问题。

要防止这种情况并不容易,因为代码库对整个公司都是开放的。很多人为此工作。

“代码库对整个公司都是开放的”不是问题。没关系

重要的是,有一个用于复制和粘贴的管理奖励系统。根本原因是,人们因复制粘贴而获得奖励(即得到报酬或称赞,晋升或延期)。

在没有从根本上将文化从“被迫尽快发布功能”转变为“获得适当的,经过良好测试的代码库更改的奖励”的情况下,您就无法打破这一点。

你必须

  1. 从顶部开始,然后是增强奖励的经理。您必须公开当前的做法并记录成本和风险。您必须提出降低成本和风险的替代方案。

  2. 您必须不懈地记录下来,并为该组织的剩余任期暴露成本和风险。狠。基于事实。成本和风险。每周都有更多的成本和更多的复制和粘贴风险。

  3. 您将不得不帮助经理人相信新方法,这会使他们看起来不错,而您将被忽略。

减少复制和粘贴非常重要。但是很难改变组织的文化。您必须提供许多事实,并且必须一遍又一遍地向不同意您的经理的理由。


1
+1尤其适用于“您必须帮助经理人相信采用新方法的新方法,这将使他们看起来不错,而您将被忽略。”。最好做好准备,使这一切经常成为现实:-(
彼得Török

@PéterTörök:太多人放弃了这一点。他们要么没有收集有关复制/粘贴引起的问题的事实,要么就没有一次又一次地向管理层提出理由。
S.Lott

我知道这里存在着更深层的非技术性问题。但这是一个没人关心的人可以很快解决的问题。这就像您需要解决的第三方库中的错误。
LennyProgrammers

@ Lenny222:您的评论毫无意义。这个问题很清楚地表明:“这是一个没人关心的问题,很快就能解决。” 这个评论是什么意思?答案中缺少什么?您还需要什么?
S.Lott

这将是一个持续的教育过程。
JeffO 2011年

5

我现在有一个从那里开始烂掉的代码库。我每个模块有10多个静态函数,这些静态函数基本上与其他模块中的相同静态函数相同。每个人的表现只是不同的足够尽快做事情的缘故,以保证新的化身。

今天,我不得不添加另一项功能,而我再也受不了了。我创建了一个新的库,将100+个函数组合为10个可重入函数,这些函数根据位标志略微更改了它们的行为,然后编写了一系列测试,以确保对该库的任何更改都不会破坏其他任何内容。

总花费时间:4小时。如果需要的话,我准备参加20小时的马拉松比赛,并且感到惊讶的是我能很快控制住不断增长的混乱状况。另外,以后修复一堆标头依赖性问题也变得容易得多。另外,由于我们许多专有的东西现在都在静态对象中进行链接,因此我们可以为客户提供比以前更多访问源代码的客户。

我的建议是:先咬紧牙关,然后立即将混乱的因素重构,以免真的变糟。可能不会花很长时间,但是为您自己创建一个新分支,以防万一。

此外,您仍然可以复制/粘贴以获取功能 解决基本问题的同时。完成后,只需剥离粘贴的内容并改用新库即可。


很好奇,您发现任何相同的东西吗?
JeffO 2011年

@Jeff-是的,几个。但是大多数情况下,这种模式表明重复是某人想要(应该是)库代码做一些不同的事情的结果。
蒂姆·波斯特

5

我同意到目前为止给出的答案。你应该:

  • 创建单元测试
  • 重构
  • 教育
  • 努力制定编码标准并发现违规情况

但是另一方面,您需要查看是什么导致人们复制粘贴并进行修复。

  • 人们可能无法以一种很好的方式重用代码,因为它与很多因素有关
  • 人们可能不知道有一个可以使用的图书馆
  • 库代码可能不够通用,并且烘焙自己的版本比使用现有库更容易
  • 可能没有很好的版本控制(不是源代码控制)策略,更改通用库可能只会导致许多其他应用程序也要进行测试。

因此,我认为要停止复制/粘贴模式,您需要使重用更加容易。

  • 使图书馆易于发现并有据可查
  • 使库独立于一切
  • 考虑一个好的版本控制策略
  • 确保向后兼容
  • 考虑库的易扩展性

阅读框架设计指南

希望这可以帮助。


3

有强烈的“复制粘贴被认为有害”的态度。我认为这很好,但是有点过分了。我认为复制粘贴作为练习来发现两种方法或类之间的异同(作为三角测量过程中的一个步骤),我认为这是健康的。但是,不进行完全三角剖分-消除复制粘贴所引起的重复-确实是有害的。

如果您能找到使用这种细微差别的态度的方法,而不是告诉开发人员“不好”,而是“那还不完整,您可以和我一起完成重构吗?”,那么您可能会发现自己在进行更具建设性的对话。


2

我在这里也遇到了同样的问题,我的看法是:不要试图避免它在先,要在它变得太糟时进行重构。

我当前正在使用的模块是另一个模块的副本,现在,我正在更改所有需要不同的内容。完成此步骤并完成新模块后,我将其与原始模块进行比较,找出哪些部分大致保持不变,应将其移至库,抽象父类等中。


2

负责的人有错。不能指望一个人来审查每一行代码,但是他们确实设置了标准和时间表。

承包商(或任何短期从事项目的人员)可以被安排到只因第一次使承包商工作而得到补偿的位置。有一些动力可以尽快完成。复制的代码可能永远都不需要修改,如果是这样,复制代码就不会被他们修改。

您可以尝试强迫他们自己解决问题。然后他们会从一开始就开始做,但是要花很多时间才能完成工作。我认为AmmoQ具有重构导致问题的事物的正确想法。


我同意。问题在于,项目经理没有动力为设计良好的代码付出更多。如果我必须浪费一个星期,则无需付费。
LennyProgrammers

@ Lenny222-您可以争取的是选择项目上的位置以使代码更好。直到他们回来(通常两腿之间有尾巴)并且需要他们感觉到的改变之后,PM的卖点才会出现,只是听到您的回答“不用担心,我们将这一部分变得更加灵活” 。他们可能最终会了解到有正确的方法来做事和管理客户的期望。每个人都想要高质量的软件,但是很少有人知道它的实际成本。
JeffO 2011年

1

消除复制/粘贴代码的唯一方法是(IMHO)代码审核,请一个人(或最好是更多个人)检查代码,并且当他们发现似乎来自复制/粘贴操作的代码时,程序员可以进行重构。


1

如建议的那样,这主要是组织中的问题。尝试从教育员工开始(不要忘记职位上方的直接管理层)。开始让一两个人坐上火车并使病毒传播非常有帮助。当大多数人认为这是一个好主意时,请对其进行描述,并尝试引入评论以确保它保持这种方式。这是一个非常缓慢而乏味的过程,但不能很快改变。首先,这将花费额外的时间,因此重要的是管理层知道并支持长期目标。

@Anders K.审查是使实践保持不变的好方法。当强迫人们编写代码时,他们不相信它会产生很多摩擦。他们会尽快回到旧的习惯。我坚信您应该从教育入手。

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.