我们都同意复制是邪恶的,应该避免(不要重复自己的原则)。 要确保使用静态分析代码,如Simian(多语言)或Clone Detective(Visual Studio加载项)
我刚读了Ayende's post about Kobe,他说的是:
8.5%的科比是副本&粘贴的代码。这就是灵敏度 拨打高,如果我们设置门槛 到3,这是我通常做的,是 达到12.5%。
我认为3作为门槛非常低。 在我的公司,我们提供高质量的代码分析即服务,我们的重复默认阈值设置为20,并且有很多重复。我无法想象如果我们将它设置为3,我们的客户甚至不可能考虑纠正。
我理解Ayende对Kobe的看法:它是一个官方样本,并且被宣传为“旨在指导您规划,构建和实施Web 2.0应用程序和服务。”因此对质量的期望很高。
但是对于您的项目,您使用什么最低阈值进行复制?
答案 0 :(得分:3)
我不知道它有什么好的“指标”,但我会说我经常努力的是
然后重构以摆脱重复。所有重复都很糟糕。我很少让代码在两个地方,而在三个地方,它肯定要去。
答案 1 :(得分:3)
三是一个很好的经验法则,但这取决于。重构以消除重复通常涉及将代码库和API的概念简单性交换为较小的代码库,一旦有人理解它就更易于维护。我一般都是从这个角度评估事物。
在一个极端情况下,如果修复重复使代码更具可读性,并且对代码的概念复杂性几乎没有增加或任何影响,那么任何重复都是不可接受的。这种情况的一个例子就是,重复的代码整齐地分解为一个简单的引用透明函数,该函数执行易于解释和命名的内容。
当需要更复杂,重量级的解决方案(如元编程,OO设计模式等)时,我可能会允许4或5个实例,尤其是在重复的代码片段很小的情况下。在这些情况下,我觉得解决方案的概念复杂性使得治疗比病情更糟,直到真的有很多实例。
在最极端的情况下,我正在使用的代码库是一个非常快速发展的原型,我对项目可能演变的方向了解不足以绘制既简单又合理的未来抽象线我只是放弃了。在像这样的代码库中,我认为最好只关注权宜之计和完成工作而不是好的设计,即使同一段代码重复20次也是如此。通常,创建所有重复的原型部分是相对较快地丢弃的部分,一旦你知道原型的哪些部分将被保留,你就可以随时重构这些部分。如果没有被丢弃的部分创建的附加约束,在这个阶段重构通常会更容易。
答案 2 :(得分:1)
我个人非常狂热。我尝试设计我的项目以避免代码重复。我的目标是将阈值设置为较低的个位数,如果我无法达到它意味着我的设计不够好,我需要回到绘图板或重构。
答案 3 :(得分:1)
取决于编程语言。 (“克隆侦探”家伙似乎认识到这一点:“编程语言限制”是他第一次演示中的方框之一。)
在Lisp程序中,任何重复表达式很容易受到重构 - 我猜你会调用那个阈值2.一切都是由表达式组成的,并且有用于翻译表达式的宏,所以很少有借口可以复制任何东西,甚至一次。 (关于我能想到的唯一难以提取的东西就像LOOP条款,实际上很多人主张出于这个原因避免使用LOOP。)
在许多其他语言中,程序由具有语句的方法组成,因此很难只提取表达式并在两个不同的文件中使用它。通常它意味着在提取物体时改变物体的结构。通常也有类型安全的要求,这可能是有限的(除非你想一直编写一个整批的反射代码来逃避它,但如果你这样做,你不应该使用静态语言)。如果我使我当前的静态类型程序完全干,那么它既不会更短也不容易维护。
我猜这个结果就是我们真正想要的是“易于维护”。有时,在某些语言中,这意味着“只需在此处发表评论,说明您复制的内容以及原因”。 DRY是可维护代码的良好指标。如果你重复了很多,那不是一个好兆头。但追逐任何一个统计数据也往往是坏事 - 否则,我们只需优化就可以解决所有问题。
答案 4 :(得分:1)
我认为我们需要结合
为了在删除重复数据的成本/收益之间取得良好的平衡。
答案 5 :(得分:0)
我们的CloneDR在大型源系统中找到重复的代码,包括精确副本和接近未命中,由langauge语法参数化。它支持Java,C#,COBOL,C ++,PHP和许多其他语言。
它接受许多参数来定义“什么是克隆?”,包括: a)相似的阈值,控制两个代码块的相似程度 要宣布克隆(通常95%是好的) b)行数最小克隆大小(3往往是一个不错的选择) c)参数数量(文本的明显变化; 5往往是一个不错的选择) 通过这些设置,它几乎可以找到10-15%的冗余代码 它处理的一切。