|
|
1
3
三是一个很好的经验法则,但这取决于具体情况。重构以消除重复通常需要用代码库和API的概念简单性来换取一个更小的代码库,一旦有人理解了它,它就更容易维护。 在一个极端情况下,如果修复重复使代码更具可读性,并且对代码的概念复杂性几乎没有增加,那么任何重复都是不可接受的。一个例子是,每当重复的代码整齐地分解成一个简单的引用透明函数时,该函数就会做一些易于解释和命名的事情。 当需要更复杂、更重量级的解决方案时,如元编程、OO设计模式等,我可能会允许4到5个实例,特别是如果重复的代码段很小。在这些情况下,我觉得解决方案的概念复杂性使治愈比生病更糟糕,直到真的有很多例子。 在最极端的情况下,我正在使用的代码库是一个发展非常迅速的原型,我对项目可能朝着什么方向发展不太了解,无法绘制出既简单又经得起未来考验的抽象线,我只是放弃了。在这样的代码库中,我认为最好只关注权宜之计和完成工作,而不是好的设计,即使同一段代码被重复了20次。通常,原型中产生所有重复的部分都是很快就会被丢弃的部分,一旦你知道原型的哪些部分会被保留,你就可以随时重构这些部分。如果没有将被丢弃的部分所创建的额外约束,在这个阶段重构通常会更容易。 |
|
|
2
3
我不知道什么是一个好的“指标”,但我会说,我通常追求的是
然后重构以消除重复。所有的重复都是不好的。我很少让代码出现在两个地方,而在三个地方,它肯定会消失。 |
|
|
3
1
我个人对此非常狂热。我试图设计我的项目以避免代码重复。我确实有一个目标,就是把阈值控制在较低的个位数,如果我不能达到这个目标,那就意味着我的设计不够好,我需要回到绘图板或重构。 |
|
|
4
1
取决于编程语言。(这位“克隆侦探”似乎认识到了这一点:“编程语言约束”是他第一次演讲中的一个方框。) 在Lisp程序中, 任何 重复的表达式很容易被重构——我想你会称之为阈值2。一切都是由表达式组成的,并且有宏来翻译表达式,所以很少有理由复制任何东西,哪怕是一次。(我能想到的唯一一件很难提取的事情就是LOOP条款,事实上,许多人正是因为这个原因而主张避免LOOP。) 在许多其他语言中,程序由具有包含语句的方法的类组成,因此很难只提取一个表达式并在两个不同的文件中使用它。通常这意味着在提取时改变事物的结构。通常还需要类型安全,这可能是限制性的(除非你想写一个 整批 始终使用反射代码来逃避它,但如果你这样做,你就不应该使用静态语言)。如果我让我当前的静态类型程序完全干燥,它既不会更短,也不会更容易维护。 我想结果是,我们真正想要的是“易于维护”。有时,在某些语言中,这意味着“只需在此处添加注释,说明你复制了什么以及为什么”。DRY是可维护代码的良好指标。如果你重复了很多,这不是一个好兆头。但追逐任何一个统计数据也往往是不好的——否则,我们只需为此进行优化即可解决所有问题。 |
|
|
5
1
我认为我们需要联合起来
以便在删除重复项的成本/收益之间进行良好的权衡。 |
|
6
0
我们的 CloneDR 在大型源代码系统中查找由langauge语法参数化的重复代码,包括精确副本和几乎未命中的代码。它支持Java、C#、COBOL、C++、PHP和许多其他语言。 它接受许多参数来定义“什么是克隆?”,包括: a) 相似性阈值,控制两个代码块必须有多相似 被宣布为克隆(通常95%是好的) b) 行数最小克隆大小(3往往是一个不错的选择) c) 参数数量(文本有明显变化;5个往往是一个不错的选择) 通过这些设置,它往往会在虚拟环境中发现10-15%的冗余代码 它处理的一切。 |
|
|
ali · flex box最佳实践 3 年前 |
|
|
Jan Wytze · Scala隔离特定平面图 7 年前 |
|
|
Scott Deerwester · 在Go中包装多个实现 7 年前 |
|
|
Moshe · 有没有办法做这个干衣机 7 年前 |
|
Josh Kelley · 惯用角形构件 7 年前 |
|
Karol Selak · 如何使用冗余的'let!`方法调用? 7 年前 |
|
|
Brandon Benefield · JS类和OOJ 7 年前 |
|
|
TheNovice · 跨两个Ruby模块继承/共享代码 8 年前 |