我正致力于重构一个体面的大型项目,我感兴趣的是搜索和减少代码克隆,以实现更好的标准化和易于开发。
我有一个在“精确匹配”中不断出现的代码片段(使用Visual 2012的“查找代码克隆”功能)。
下面是:
End If
End Using
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Using
End Using
Return Nothing
基本上,我有一大堆类似的函数(在结构上相似,但在实际功能上不一样),它们都是以如下方式打开的:
Const sql As String = ...
Using cn As SqlConnection...
Using cmd As SqlCommand(sql,cn)
... Maybe add some SqlParameters
cn.Open()
... Something with cmd.Execute...
现在,我认识到第一个代码块是跨许多方法的完全相同的,但是我想不出一种方法来提取该代码,编写它一次,并且每次我需要该功能时都简单地调用它。在我看来,有太多的控制流发生了。
因此,我对如何解决这个问题感到困惑(我只是假设我可以“修复”这个问题,因为微软已经将其识别为“克隆代码”)。
我正在考虑一些类似于创建少量执行相同的类型的的函数(比如从表中返回一个计数,返回一个顶值等等)。而且只有执行的SQL才有真正的不同。不过,这可能有点棘手,因为有时参数(类型和数字)有所不同。
有什么想法吗?
发布于 2013-01-02 16:50:28
我不关心你自己。你的常识第一印象是正确的。虽然从技术上讲,语法是多次重复的,但它实际上并不是逻辑的重复,也不是任何一种算法。这并不是说没有办法减少重复,只是这样做的话,您的代码中可能会出现更糟糕的设计。
例如,您可以创建一个方法来执行所有的设置和拆卸,然后只调用中间的一个方法,该方法实际上使用连接来完成工作,例如:
Public Function PerformDbTask(task As IMyDbTask)
Using cn As SqlConnection...
Using cmd As SqlCommand = cn.CreateCommand()
Try
cn.Open()
task.Perform(cmd)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Using
End Using
Return Nothing
End Function
然而,你真正得到了什么呢?可能一点也不多,但是您已经失去了很多灵活性。所以,除非这种设计对你想要做的事情是必要的,否则我不会浪费时间去解决一个根本不存在的问题。
发布于 2013-01-02 16:44:40
您可以创建一个实现构建器模式的类,该类最后看起来像
Dim list =
SqlBuilder.Query("SELECT ...")
.WithConnection("...connection string...")
.WithParameter(userName)
.WithParameter(lastTrackId)
.RetrieveTopRows(10)
发布于 2013-01-02 18:00:58
您的问题是,您使用的是与令牌序列匹配的克隆检测器(因此它与您展示的块结束序列相匹配),而不是匹配代码结构的克隆检测器。虽然令牌序列在技术上是一个克隆,但它不是一个有趣的克隆。令牌克隆检测器产生许多这样的“假阳性”克隆,这只是浪费您的时间。
构建令牌序列检测器更容易,这就是他们将其内置到MS中的原因。如果你想要更好的探测器,你必须走出工作室。
您应该查看与抽象语法树匹配的克隆检测器。他们不会产生这种假阳性,他们可以找到具有复杂参数的克隆(相对于单个标记参数)。
您还应该理解,仅仅因为某些东西已经被识别为克隆,重构它并不总是容易或可能的。您所拥有的语言可能没有足够强大的抽象机制来处理这种情况。
https://stackoverflow.com/questions/14125571
复制相似问题