Работа с объектами бога

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

Например, представьте, что вам просто предоставили службу Windows для работы. Теперь в этой службе есть ошибка, и вам нужно выяснить, что делает служба, прежде чем вы сможете надеяться на ее исправление. Вы открываете сервис и видите, что кто-то решил просто использовать один файл для всего. Здесь используется метод "Старт", метод "Стоп", "Таймеры", вся обработка и функциональность. Я говорю тысячи строк кода. Методы, содержащие более сотни строк кода, встречаются редко.

Теперь, полагая, что вы не можете переписать весь класс, и эти божественные классы просто будут всплывать, что лучше всего с ними справиться? С чего начать? Что вы пытаетесь выполнить в первую очередь? Как вы справляетесь с подобными вещами, а не просто хотите, чтобы все было стабильно.

Если у вас есть стратегия только для того, чтобы держать себя в курсе, это тоже приветствуется.

Советы таким образом:

  • Установить зону тестирования
  • Сложение кода
  • Реорганизовать существующие методы
  • Поведение документа как обнаруженное
  • Цель постепенного улучшения

Edit:

Чарльз Конвей рекомендует подкаст, который оказался очень полезным. ссылка

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

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

Великий совет Возьмите большой класс, который используется в другом месте и реализует интерфейс emtpy. Затем возьмите код с помощью класса и попробуйте вместо него создать экземпляр интерфейса. Это даст вам полный список всех зависимостей этого большого класса в вашем коде.

Ответ 1

Ой! Звучит как место, которое я использую для работы.

Взгляните на Эффективно работать с устаревшим кодом. У него есть некоторые драгоценности о том, как бороться с зверским кодом.

Недавно DotNetRocks выполнил show при работе с устаревшим кодом. Нет волшебной таблетки, которая заставит ее работать.

Лучший совет, который я слышал, - это постепенное завершение кода в тестах.

Ответ 2

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

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

Ответ 3

Даже если вы не можете реорганизовать файл, попробуйте его реорганизовать. Переместите методы/функции так, чтобы они, по крайней мере, были организованы внутри файла логически. Затем добавьте много комментариев, объясняющих каждый раздел. Нет, вы не переписали программу, но по крайней мере сейчас вы можете ее правильно прочитать, и в следующий раз, когда вам придется работать над файлом, у вас будет много комментариев, написанных вами (что, надеюсь, означает, что вы будете быть в состоянии понять их), которые помогут вам справиться с программой.

Ответ 4

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

Скрыть все, и вы вернулись к парадигме C, за исключением складок, а не отдельных файлов.

Ответ 5

Я тоже столкнулся с этой ситуацией.

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

Во-вторых, я идентифицирую основной алгоритм и разлагаю их на свои части, используя систему нумерации, которая чередуется между числами и буквами (это уродливо, но хорошо работает для меня). Например, вы могли бы взглянуть на часть алгоритма 4 "уровня" в глубину, и нумерация будет 1.b.3.e или каким-то другим богом ужасным. Обратите внимание, что, когда я говорю уровни, я не имею в виду непосредственно управление блоками или областью действия, но где я определил шаги и подэтапы алгоритма.

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

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

Ответ 6

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

Я получил исходный код. Один файл, 22 000 строк C, абстракция. Я часами читал его; была вся эта великая работа, но все было сделано плохо. Я не смог повторно использовать одну строку или даже одну идею.

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

Ответ 7

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

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

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