我正在写一个JS webapp客户端.用户可以编辑文本项的列表/树(例如,待办事项列表或备注).我用jQuery操作DOM很多.
用户可以使用键盘上下导航列表(类似于GMail中的J/K键),并执行其他几项操作.这些操作中的许多操作具有镜像"向上"/"向下"功能,例如
$.fn.moveItemUp = function() {
var prev = this.getPreviousItem();
prev && this.insertBefore(prev);
// there's a bit more code in here, but the idea is pretty simple,
// i.e. move the item up if there's a previous item in the list
}
$.fn.moveItemDown = function() {
var next = this.getNextItem();
next && this.insertAfter(next);
// ....
}
Run Code Online (Sandbox Code Playgroud)
现在这个具有两个几乎相同的函数的模式在我的代码中的几个地方重复,因为在列表/树上有许多操作非常对称.
问题:如何优雅地重构这一点以避免代码重复?
到目前为止我提出的琐碎方法是使用.apply()......
$.fn.moveItem = function(direction) {
var up = direction === 'up',
sibling = up ? this.getPreviousItem() : this.getNextItem(),
func = …Run Code Online (Sandbox Code Playgroud) 我一直在阅读一些汇编编程视频,以便更好地理解如何手动优化编译后留下的*.s文件.gcc/g++ -S ... 其中一个主题是重构冗余代码,演示如何将冗余代码移动到自己的标记块以ret结束并用呼叫替换它.
视频中给出的示例是2个块,包含:
mov eax,power
mul ebx
mov power,eax
inc count
Run Code Online (Sandbox Code Playgroud)
它取而代之的是call CalculateNextPower和CalculateNextPower看起来像:
CalculateNextPower:
mov eax,power
mul ebx
mov power,eax
inc count
ret
Run Code Online (Sandbox Code Playgroud)
出于好奇,试图减少编译大小,我用-S和各种优化编译了一些C和C++项目,包括-Os,-O2,-O3,-pipe,-combine和-fwhole-program,并分析了结果*.s使用轻微修补(for .s文件)版本的duplo进行冗余的文件.只有-fwhole-program (现已弃用的IIRC)对消除文件中的重复代码有显着影响(我认为它的替换(-s)-flto在链接时会表现相似 - 大致相当于用-ffunction-sections -fdata-sections编译和--gc-sections链接)但仍然错过了大量的代码块.
使用duplo输出的手动优化导致随机C项目的大小减少约10%,并且当仅具有至少5个连续重复指令的连续块组件被重复数据删除时,随机C++项目中几乎减少30%.
我是否遗漏了一个编译器选项(甚至是一个独立的工具),在编译大小时会自动消除冗余程序集(包括其他编译器:clang,icc等等) 或者是否缺少此功能(原因?)?
如果它不存在,则可以修改duplo以忽略以'.'开头的行.要么 ';' (以及其他人?)并使用重复代码调用函数替换重复的代码块,但我对其他可直接使用编译器内部表示(最好是clang或gcc)的建议持开放态度.
编辑:我修补杜普洛识别重复组装块在这里,但它仍然需要在此刻手动重构.只要使用相同的编译器生成代码,就可以(但可能很慢)识别最大的重复代码块,将它们放在自己的"函数"块中,并用CALL替换代码到该块.
通常我发现自己处于一种情况,我有一个具有许多可选参数的超类,并且这些相同的参数也需要在其子类中是可选参数.
例如,超类:
abstract class Plugin(val name: String, val version: String = "1.0",
val author: String = "", val description: String = "")
Run Code Online (Sandbox Code Playgroud)
扩展这个课程是一件痛苦的事.这是一个示例子类:
abstract class CyclePlugin(name: String, version: String = "1.0", author: String = "",
description: String = "", val duration: Int, val durationUnit: TimeUnit
= MILLISECONDS) : Plugin(name, version, author, description)
Run Code Online (Sandbox Code Playgroud)
注意:我将用我的解决方案回答这个问题.我正在寻找更好的解决方案.
我有一些研究代码是一个真正的老鼠窝,到处都是代码重复,显然需要重构.但是,随着我对主题的新变化提出并使它们适合代码库,代码库也在不断发展.我推迟重构这么久的原因是因为我觉得我花了几天时间提出好的抽象,看看哪些设计模式适合哪里,等等,我想尝试一些新的无法预料的想法,使我的抽象完全不合适.换句话说,由于代码的演变速度,我真的不知道抽象线在哪里,即使没有(近似)重复的缺乏,代码的一般混乱使得添加内容真实痛.
是否有任何工具可以检测JavaScript中的代码重复?我尝试了“ PMD重复代码检测器”,但它不支持.js扩展名。
有没有办法让我可以使复制构造函数和赋值运算符的主体包含相同的代码,而实际上没有重复的代码(函数头除外)?
c++ constructor code-duplication copy-constructor assignment-operator
我正在管理一个由三名实习生组成的小组,他们正在从事一个 php 项目。他们似乎不擅长重构,并且在多个地方使用重复的代码。我正在寻找一个工具,我可以用它来找到这个重复的代码,以便我可以展示它们。
这将使我的工作更轻松,项目更优雅,更不容易出错。任何线索?
我有一个正在由Sonar 3.0.1进行分析的Groovy项目.我们使用声纳探测器打开了重复的代码检测.
在一组文件中,它检测到11行重复的import语句.在另一组文件中,它检测到15行重复的成员声明.由于这个项目清楚地分离了数据库与显示对象(即使它们大部分相似,因此重复的成员声明),我想配置Sonar忽略这些重复集 - 我们认为它们是可接受的重复.
我怎么能告诉Sonar忽略重复的导入和/或成员声明,但是仍然因为方法中的重复代码而对我大喊大叫?
在实现诸如iterator和/ const_iterator或类似的类对时避免代码重复的最佳实践是什么?
这似乎是一个普遍的问题,有一个规范的解决方案,但我没有找到任何专门的文章.
示例:我想从这些运算符函数中提取嵌套的 for 循环,这些运算符函数除了一行之外都是相同的。
// Add two matrices
Matrix& operator+=(const Matrix& other)
{
for (int i = 0; i < this->m_rows; i++)
{
for (int j = 0; j < this->m_cols; j++)
{
(*this)(i, j) = (*this)(i, j) + other(i, j); // Only difference
}
}
return *this;
}
// Subtract two matrices
Matrix& operator-=(const Matrix& other)
{
for (int i = 0; i < this->m_rows; i++)
{
for (int j = 0; j < this->m_cols; j++)
{
(*this)(i, j) = …Run Code Online (Sandbox Code Playgroud) code-duplication ×10
c++ ×3
refactoring ×3
constructor ×2
duplicates ×2
javascript ×2
assembly ×1
class-design ×1
coding-style ×1
const ×1
groovy ×1
jquery ×1
kotlin ×1
size ×1
sonarqube ×1