В C # (или на любом другом языке) какой ваш любимый способ удаления повторений? - PullRequest
4 голосов
/ 13 сентября 2008

Я только что написал класс из 700 строк. Ужасно. Я опускаю голову от стыда. Это так же противоположно DRY , как британское лето.

Он полон вырезок и вставок с небольшими изменениями здесь и там. Это делает его главным кандидатом на рефакторинг. Прежде чем приступить к этому, я подумал, что когда у вас будет много повторений, я бы спросил, какие первые возможности рефакторинга вы ищете?

Для записи, мои, вероятно, используют:

  1. Общие классы и методы
  2. Метод перегрузки / сцепления.

Какие у вас?

Ответы [ 7 ]

4 голосов
/ 13 сентября 2008

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

Методы, которые вы используете для рефакторинга, должны начинаться с самых простых. Я настоятельно рекомендую книгу Мартина Фаулера. Объединение общего кода в функции, удаление ненужных переменных и другие простые методы принесут вам много пользы. Для операций со списком я предпочитаю использовать идиомы функционального программирования. То есть я использую внутренние итераторы, map, filter и redux (на языке Python, когда есть возможность, в ruby, lisp и haskell есть соответствующие вещи), это делает код намного короче и более автономным.

2 голосов
/ 13 сентября 2008

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

По моему личному опыту, моим любимым "способом удаления повторений" была функция "Извлечь метод" из Resharper (хотя это также доступно в vanilla Visual Studio).

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

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

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

2 голосов
/ 13 сентября 2008

# регион

Я сделал класс из 1000 строк только с одной строкой!

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

1 голос
/ 13 сентября 2008

Я мог бы пойти что-то вроде этого:

Создание пользовательских (частных) типов для структур данных и размещение всей связанной логики. Словарь <строка, список <int>> и т. Д.

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

Сплит методы, которые имеют слишком много дел. Если вы не можете поместить что-то сжатое в или дать ему хорошее имя, тогда начните разбивать функцию на части, пока код не станет (даже если эти «дочерние» функции больше нигде не используются).

Если ничего не помогает, добавьте [SuppressMessage («Microsoft.Maintainability», «CA1502: AvoidExcessiveComplexity»)] и прокомментируйте, почему.

1 голос
/ 13 сентября 2008

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

Есть также несколько простых техник для удаления повторяющихся блоков if / else if и switch, любезно предоставленных Скоттом Хансельманом: http://www.hanselman.com/blog/CategoryView.aspx?category=Source+Code&page=2

1 голос
/ 13 сентября 2008

Одна из вещей, которые я делаю, это стараюсь делать маленькие и простые методы, которые я вижу на одной странице в моем редакторе (visual studio).

Из опыта я узнал, что упрощение кода облегчает его компилятору. Чем больше метод, тем сложнее должен работать компилятор!

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

while (true)
{
  var smallObject = WaitForSomethingToTurnUp();
  var largeObject = DoSomethingWithSmallObject();
}

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

Я легко решил эту проблему, переместив DoSomethingWithSmallObject () и другой связанный код в другой метод.

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

Надеюсь, это поможет.

Ник

1 голос
/ 13 сентября 2008

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

Что касается моего любимого способа удаления дублирования .... Замыкания, особенно на моем любимом языке (Ruby). Они имеют тенденцию быть действительно кратким способом взять 2 куска кода и объединить сходства. Конечно (как любая «лучшая практика» или совет), это не может быть сделано вслепую ... Я просто нахожу их действительно забавными, когда я могу их использовать.

...