Как управлять частными случаями и эвристикой - PullRequest
6 голосов
/ 06 июня 2009

У меня часто есть код, основанный на определенном четко определенном алгоритме. Это хорошо прокомментировано и кажется правильным. Для большинства наборов данных алгоритм отлично работает.

Но затем добавляются граничные случаи, особые случаи, эвристика для решения конкретных задач с определенными наборами данных. По мере роста числа особых случаев комментарии становятся все более туманными. Я боюсь вернуться и посмотреть на этот код через год или около того и попытаться вспомнить, почему был добавлен каждый особый случай или эвристика.

Иногда мне хотелось бы, чтобы был способ встраивать или связывать графику в исходном коде, чтобы я мог эффективно сказать: «На графике этого набора данных именно эта особенность здесь вызывала неправильное срабатывание подпрограммы, поэтому этот кусок кода был добавлен ".

Каковы некоторые передовые практики для решения подобных ситуаций?

Особые случаи, кажется, всегда требуются для обработки этих необычных / крайних случаев. Как им можно управлять, чтобы код был относительно читабельным и понятным?

Рассмотрим пример, касающийся распознавания функций по фотографиям (не совсем то, над чем я работаю, но аналогия кажется подходящей). Когда я нахожу конкретную картинку, для которой общий алгоритм не работает и требуется особый случай, я записываю эту информацию как можно лучше в комментарии (или, как кто-то предложил ниже, описательное имя функции). Но часто не хватает постоянной ссылки на конкретный файл данных, который демонстрирует рассматриваемое поведение. В то время как мой комментарий должен описывать проблему и, вероятно, сказал бы «посмотрите файл foo.jp для примера такого поведения», этот файл никогда не находится в дереве исходного кода и может легко потеряться.

В таких случаях люди добавляют файлы данных в исходное дерево для справки?

Ответы [ 8 ]

6 голосов
/ 06 июня 2009

Мартин Фаулер сказал в своей книге по рефакторингу, что когда вы чувствуете необходимость добавить комментарий к своему коду, сначала посмотрите, можете ли вы инкапсулировать этот код в метод и дать методу имя, которое заменит комментарий.

чтобы в качестве резюме вы могли создать метод с именем.

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;
}

Тогда вы можете написать код, как

if(ConditionXAndYHaveOccurred(myObject))
{
    myObject = ApplySolutionForEdgeCaseWhenXAndYHappen(myObject);
}

Не жесткий и быстрый конкретный пример, но он поможет с удобочитаемостью через год или два.

4 голосов
/ 06 июня 2009

Модульное тестирование может помочь здесь. Наличие тестов, которые фактически имитируют особые случаи, часто может служить документацией о том, почему код делает то, что делает. Это часто может быть лучше, чем просто описание проблемы в комментарии.

Не то чтобы это заменяло перемещение обработки особого случая на их собственные функции и достойные комментарии ...

2 голосов
/ 06 июня 2009

Если у вас есть база знаний или вики для проекта, вы можете добавить в нее график, ссылаясь на него в методе в соответствии с цитата Фаулера Мэтью e, а также в сообщении коммита управления источником для изменения крайнего случая.

//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

Это больше работы, но способ документировать случаи более тщательно, чем простые тестовые примеры или комментарии. Даже если можно утверждать, что тестовые примеры должны быть достаточно документированы, вы, возможно, не захотите хранить в нем весь набор ошибочных данных, например.

Помните, что неопределенные проблемы приводят к неопределенным решениям.

1 голос
/ 06 июня 2009

Дон Кнут изобрел грамотное программирование , чтобы упростить документацию вашей программы для включения графиков, графиков, диаграмм, математических уравнений и всего, что вам нужно для понимания. Грамотная программа - отличный способ объяснить, почему что-то такое, как оно есть, и как оно получилось со временем. Существует много, много инструментов для грамотного программирования; инструмент noweb является одним из самых простых и поставляется с некоторыми дистрибутивами Linux.

1 голос
/ 06 июня 2009

О

Иногда мне хотелось бы, чтобы был способ встраивать или связывать графику в исходном коде, так что я мог бы сказать эффективно, "на графике этого набора данных, этот конкретный функция здесь заставляла подпрограмму некорректно срабатывать, поэтому код был добавлен ".

часть:

Если «графический объект», который вы хотите встроить, является графиком, и если вы используете Doxygen , вы можете встроить команды dot в ваш комментарий, чтобы создать график в документации :

/**
If we have a subgraph looking like this:
\dot
digraph g{
A->B;
A->C;
B->C;
}
\enddot
the usual method does not work well and we use this heuristic instead.
*/
1 голос
/ 06 июня 2009

Я обычно не сторонник разработки, ориентированной на тестирование, и подобных стилей, которые слишком сильно стресс-тестируют, но, похоже, это идеальный случай, когда куча модульных тестов может очень помочь. И даже не в первую очередь для выявления ошибок от более поздних изменений, а просто для документирования всех особых случаев, которые необходимо устранить.

Несколько хороших юнит-тестов с комментариями в них сами по себе являются лучшим описанием особых случаев. И комментирование самого кода тоже становится проще. Можно просто указать на некоторые модульные тесты, которые иллюстрируют проблему, которая решается в этот момент кода.

0 голосов
/ 06 июня 2009

Похоже, вам нужна более тщательная документация, чем просто комментарии кода. Таким образом, кто-то может найти нужную функцию в документации и получить пример изображения, требующего особого случая.

0 голосов
/ 06 июня 2009

Не зная специфики вашей проблемы, нелегко дать ответ, но из моего собственного опыта следует избегать обработки особых случаев в жестком коде. Разве вы не задумывались о реализации механизма правил или чего-то подобного для обработки особых случаев вне вашего основного алгоритма обработки?

...