首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用Java管理高度重复的代码和文档

用Java管理高度重复的代码和文档
EN

Stack Overflow用户
提问于 2010-02-26 03:59:01
回答 9查看 5.4K关注 0票数 72

高度重复的代码通常是一件坏事,有一些设计模式可以帮助最小化这种情况。然而,有时由于语言本身的限制,这是不可避免的。以java.util.Arrays的以下示例为例

/**
 * Assigns the specified long value to each element of the specified
 * range of the specified array of longs.  The range to be filled
 * extends from index <tt>fromIndex</tt>, inclusive, to index
 * <tt>toIndex</tt>, exclusive.  (If <tt>fromIndex==toIndex</tt>, the
 * range to be filled is empty.)
 *
 * @param a the array to be filled
 * @param fromIndex the index of the first element (inclusive) to be
 *        filled with the specified value
 * @param toIndex the index of the last element (exclusive) to be
 *        filled with the specified value
 * @param val the value to be stored in all elements of the array
 * @throws IllegalArgumentException if <tt>fromIndex &gt; toIndex</tt>
 * @throws ArrayIndexOutOfBoundsException if <tt>fromIndex &lt; 0</tt> or
 *         <tt>toIndex &gt; a.length</tt>
 */
public static void fill(long[] a, int fromIndex, int toIndex, long val) {
    rangeCheck(a.length, fromIndex, toIndex);
    for (int i=fromIndex; i<toIndex; i++)
        a[i] = val;
}

上述代码片段在源代码中出现了8次,文档/方法签名几乎没有变化,但方法主体完全相同,分别对应于int[]short[]char[]byte[]boolean[]double[]float[]Object[]根数组类型。

我相信,除非一个人求助于反思(这本身是一个完全不同的主题),否则这种重复是不可避免的。我知道作为一个实用类,如此高度集中的重复性Java代码是非常不典型的,但即使是在最佳实践中,也会发生重复!重构并不总是有效的,因为它并不总是可行的(最明显的情况是在文档中出现重复的情况)。

显然,维护这些源代码是一场噩梦。文档中的一个小的打字错误,或者实现中的一个小错误,都会被重复的次数成倍增加。实际上,最好的例子恰好涉及到这个类:

Google Research Blog - Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken (by Joshua Bloch, Software Engineer)

这是一个令人惊讶的微妙错误,发生在许多人认为只是一个简单和直接的算法。

    // int mid =(low + high) / 2; // the bug
    int mid = (low + high) >>> 1; // the fix

在源代码!中,上面的行出现了11次!

所以我的问题是:

  • 这些重复的Java代码/文档在实践中是如何处理的?它们是如何开发、维护和测试的?您是否从“原始文件”开始,并使其尽可能成熟,然后根据需要复制和粘贴,并希望您没有犯错误?
  • 和如果您确实在原始文件中犯了错误,则只需在任何地方修复它,除非您对删除副本并重复整个复制过程感到满意?
  • 和您对测试代码应用与well?

相同的过程

对于这类事情,

  • 会从某种有限使用的源代码预处理中获益吗?
    • 可能有自己的预处理器来帮助编写、维护、记录和测试这些重复的库Java

一个评论需要另一个例子,所以我从谷歌集合中提取了这个例子:com.google.common.base.Predicates第276-310行(AndPredicate) vs第312-346行(OrPredicate)。

这两个类的源代码是相同的,除了:

  • AndPredicate vs OrPredicate (每一个都在其class)
  • "And(" vs代码中出现5次(在相应的代码methods)
  • #and vs #or中(在@see Javadoc expression)
  • -1 /* all bits on */ vs apply中;可以在hashCode()

中重写出OrPredicate vs Or("中的toString() vs !

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-02-26 12:06:52

对于绝对需要性能的人来说,装箱、拆箱和泛化集合等都是大忌。

同样的问题也发生在性能计算中,你需要相同的复杂结构才能同时处理浮点数和双精度浮点数(比如Goldberd的"“论文中展示的一些方法)。

这就是为什么在处理类似数量的数据时,TroveTIntIntHashMap会绕过HashMap<Integer,Integer>

那么Trove集合的源代码是如何编写的呢?

当然,通过使用源代码插装:)

有几个Java库可以获得更高的性能(远高于默认的Java库),它们使用代码生成器来创建重复的源代码。

我们都知道“源代码插装”是邪恶的,代码生成是垃圾,但这仍然是那些真正知道自己在做什么的人(即编写像Trove这样的东西的人)所做的事情:)

值得注意的是,我们生成的源代码包含大量警告,例如:

/*
 * This .java source file has been auto-generated from the template xxxxx
 * 
 * DO NOT MODIFY THIS FILE FOR IT SHALL GET OVERWRITTEN
 * 
 */
票数 32
EN

Stack Overflow用户

发布于 2010-02-26 04:10:52

如果您一定要复制代码,请遵循您给出的很好的示例,并将所有代码分组在一个地方,这样当您必须进行更改时,就很容易找到和修复这些代码。记录复制,更重要的是,记录复制的原因,以便在您之后的每个人都能意识到这两点。

票数 16
EN

Stack Overflow用户

发布于 2010-02-26 04:20:26

来自Wikipedia不要重复自己(DRY)或复制是邪恶的(DIE)

在某些情况下,强制执行DRY哲学所需的努力可能比维护单独的数据副本的努力更大。在其他一些上下文中,复制的信息是不可变的,或者受到足够严密的控制,以使DRY不是必需的。

可能没有答案或技术来防止类似的问题。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2337170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档