如何管理特殊情况和启发式

lon*_*ger 6 c c++ literate-programming

我经常使用基于特定定义算法的代码.这得到了很好的评论,似乎是正确的.对于大多数数据集,算法运行良好.

但随后边缘情况,特殊情况,启发式方法被添加以解决特定数据集的特定问题.随着特殊情况的数量增加,评论越来越模糊.我担心在一年左右的时间内回过头来查看这段代码并试图记住为什么会添加每个特殊的特例或启发式.

我有时希望有一种方法可以在源代码中嵌入或链接图形,所以我可以有效地说,"在这个数据集的图形中,这个特殊功能导致例程不正确地触发,所以这就是为什么这个代码被添加".

处理这种情况的最佳做法是什么?

似乎总是需要特殊情况来处理这些异常/边缘情况.如何管理它们以使代码保持相对可读性和可理解性?

考虑一个处理照片特征识别的例子(不完全是我正在研究的,但类比似乎很合适).当我找到一般算法失败并且需要特殊情况的特定图片时,我尽可能地在评论中记录该信息(或者如下面的某人建议的描述性函数名称).但是经常缺少的是指向展示相关行为的特定数据文件的永久链接.虽然我的评论应该描述这个问题,并且可能会说"请参阅文件foo.jp以获取此行为的示例",但此文件永远不会出现在源代码树中,并且很容易丢失.

在这种情况下,人们是否会将数据文件添加到源树中以供参考?

Mat*_*nes 6

Martin Fowler在他的重构书中说,当你觉得需要在你的代码中添加注释时,首先要看看你是否可以将该代码封装到一个方法中,并为该方法命名,以取代注释.

所以作为一个摘要,你可以创建一个名为的方法.

private bool ConditionXAndYHaveOccurred(object param)
{
   // code to check for conditions x and y
   return result;
}

private object ApplySolutionForEdgeCaseWhenXAndYHappen(object param)
{
   //modify param to solve for edge case
   return param;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以写代码

if(ConditionXAndYHaveOccurred(myObject))
{
    myObject = ApplySolutionForEdgeCaseWhenXAndYHappen(myObject);
}
Run Code Online (Sandbox Code Playgroud)

这不是一个硬性和快速的具体例子,但它有助于在一两年内实现可读性.


Vin*_*vic 2

如果您有该项目的知识库或 wiki,您可以在其中添加图表,按照Matthew 的 Fowler 引用的方法以及在边缘情况更改的源代码控制提交消息中链接到它。

//See description at KB#2312
private object SolveXAndYEdgeCase(object param)
{
   //modify param to solve for edge case
   return param;
}

Commit Message: Solution for X and Y edge case, see description at KB#2312
Run Code Online (Sandbox Code Playgroud)

这是更多的工作,但却是一种比单纯的测试用例或注释更彻底地记录用例的方法。例如,尽管有人可能会认为测试用例应该有足够的文档,但您可能不希望将整个失败数据集存储在其中。

请记住,模糊的问题会导致模糊的解决方案。