代码重复

代码重复(英文:duplicate code,也叫代码克隆)在程序设计中表示一段源代码在一个程序,或者一个团体所维护的不同程序中重复出现,是不希望出现的现象。为避免巧合,只有一定数量的代码完全相同才能判定为代码重复。重复代码的段落有时被称为代码克隆,自动检测代码重复的过程叫做克隆检测

产生

产生代码重复可能有以下几个原因:

  • 因为某段代码能用就复制粘贴过来。多数情况下代码会有少许不同,如变量名称改变或代码增删。
  • 因为要实现与已有功能类似的功能,开发者独立写出与别处相似的代码。研究表明独立撰写的代码在语法上不一定相似。[1]
  • 抄袭,即不经允许复制代码,且未列出版权归属。
  • 代码系自动生成。这时可能需要重复代码以提高性能或方便开发。注:这里代码重复是指代码生成器自动生成的代码,而非生成器本身的代码。

成本与效益

不恰当的代码重复表明程序设计不良,例如缺少抽象。这会导致程序过长,错误更多,进而难以维护,因为需要人工寻找并修改重复的部分。[2]然而由于种种原因,适当的代码重复难以避免,例如给与已有设备相似的新设备写驱动程序时,复制代码能使开发更便捷。[3]

当复制具有软件漏洞的代码时,如果开发人员不知道这样的副本,则复制的代码中可能会继续存在漏洞。代码重构可以改善许多软件的度量衡标准,例如源代码行数,循环复杂度耦合度。这可能会缩短编译时间,降低认知负载,减少人为错误,减少被遗忘或被忽视的代码。

但并不是所有的代码重复都可以被重构。如果编程语言提供不充分或过于复杂的抽象,克隆或许是具有速度效益上的解决方式,特别是修改代码使用的编辑器如有支持区块(行)编辑的功能。而且,重构时破坏代码的风险可能会超过维护的效益。重复的代码似乎不会比不重复的代码更容易出错。使用开源方式共享代码组件,而不是在软件配置管理的仓储库之间复制它们,也可以减少复制。

检测

检测代码重复的手段有:

例子

以计算整数数组平均值的代码片段为例

extern int array1[];
extern int array2[];
 
int sum1 = 0;
int sum2 = 0;
int average1 = 0;
int average2 = 0;
 
for (int i = 0; i < 4; i++)
{
   sum1 += array1[i];
}
average1 = sum1/4;
 
for (int i = 0; i < 4; i++)
{
   sum2 += array2[i];
}
average2 = sum2/4;

这两个循环可以改写为一个函数:

int calcAverage (int* Array_of_4)
{
   int sum = 0;
   for (int i = 0; i < 4; i++)
   {
       sum += Array_of_4[i];
   }
   return sum/4;
}

利用以上函数可以写出无重复的源代码

extern int array1[];
extern int array2[];

int average1 = calcAverage(array1);
int average2 = calcAverage(array2);
 
Example of duplicate code fix via code replaced by the method

参见

参考资料

  1. ^ Code similarities beyond copy & paste页面存档备份,存于互联网档案馆) by Elmar Juergens, Florian Deissenboeck, Benjamin Hummel.
  2. ^ Spinellis, Diomidis. The Bad Code Spotter's Guide. InformIT.com. [2008-06-06]. (原始内容存档于2012-10-18). 
  3. ^ Kapser, C.; Godfrey, M.W., ""Cloning Considered Harmful" Considered Harmful页面存档备份,存于互联网档案馆)," 13th Working Conference on Reverse Engineering (WCRE), pp. 19-28, Oct. 2006
  4. ^ Brenda S. Baker. A Program for Identifying Duplicated Code. Computing Science and Statistics,24:49–57, 1992.
  5. ^ Ira D. Baxter, et al. Clone Detection Using Abstract Syntax Trees页面存档备份,存于互联网档案馆
  6. ^ Visual Detection of Duplicated Code页面存档备份,存于互联网档案馆) by Matthias Rieger, Stephane Ducasse.
  7. ^ Yuan, Y. and Guo, Y. CMCD: Count Matrix Based Code Clone Detection, in 2011 18th Asia-Pacific Software Engineering Conference. IEEE, Dec. 2011, pp. 250–257.
  8. ^ Chen, X., Wang, A. Y., & Tempero, E. D. (2014). A Replication and Reproduction of Code Clone Detection Studies页面存档备份,存于互联网档案馆). In ACSC (pp. 105-114).