Как управлять особыми случаями и эвристикой

StackOverflow https://stackoverflow.com/questions/958003

  •  12-09-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

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

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

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

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

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

О том, что

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

часть:

Если "графическое изображение", которое вы хотите встроить, является графиком, и если вы используете Токсиген, вы можете встроить точка команды в вашем комментарии для создания графика в документации:

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top