2008-12-12 3 views
11

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

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

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

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

советы до сих пор:

  1. Создание тестового покрытия
  2. свертывание кода
  3. реорганизовать существующие методы поведения
  4. Документ, как обнаружил
  5. Aim для инкрементного улучшения

Edit:

Charles Conway рекомендует подкаст, который оказался очень полезным. link

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

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

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

+3

Бегите, и не останавливайтесь, чтобы оглянуться! – JoshBerke 2008-12-12 04:29:57

+0

Если бы я мог Джош ... Если бы только я мог ... – 2008-12-12 04:32:00

+0

Хе-хе, я слышал, мне когда-то пришлось пересмотреть это многопоточное 200-миллиметровое строковое приложение COM +, оно имело циклические величины сложности выше, чем когда-либо видел. Ох, и это было всего лишь как 5 методов. Я помахал и рассмеялся над Mgmt за то, что предложил нам «повторно использовать» эту услугу. – JoshBerke 2008-12-12 04:42:10

ответ

9

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

Посмотрите на Working effectivly with legacy code. У него есть некоторые драгоценности о том, как бороться с зверским кодом.

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

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

4

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

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

3

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

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

4

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

2

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

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

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

3

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

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

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

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

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

3

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

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

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