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

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

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

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

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

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

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

Редактировать:

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

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

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

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

Беги и не оглядывайся !!!

JoshBerke 12.12.2008 07:29

Если бы я только мог, Джош ... Если бы я только мог ...

Ty. 12.12.2008 07:32

Хех, я слышал, да, мне когда-то приходилось проверять это многопоточное приложение COM +, 20000 строк кода, циклическая сложность которого была выше, чем я когда-либо видел. Ох, а всего было 5 способов. Я рванул и посмеялся над Mgmt за то, что он предложил «повторно использовать» эту службу.

JoshBerke 12.12.2008 07:42

И я хотел бы получить лучший совет, но .... Я знаю боль ...

JoshBerke 12.12.2008 07:43

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

Ty. 12.12.2008 08:06

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

JoshBerke 12.12.2008 08:18

@Ty: имейте в виду, что как только вы нажмете 7 правок, вопрос превратится в вики сообщества. Добавление каждого совета, как только он появляется, может привести вас к нему раньше, чем вы захотите. ;-)

Tomalak 12.12.2008 10:16

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

Ty. 12.12.2008 18:01

Ха, языковой агностик возражает против Бога. Иронично?

Marcelo MD 12.12.2008 18:43

Просто сказать нет. Не создавайте объекты Бога. В Советской России вас создают объекты Бога! Ой, подождите, что?

Windows programmer 19.12.2008 09:21
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
12
10
1 434
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

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

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

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

Большая часть кодовой базы носит довольно процедурный характер, поэтому поиск решений этой проблемы, которые были обработаны на C, тоже может быть хорошим местом. Спасибо!

Ty. 12.12.2008 07:27

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

tvanfosson 12.12.2008 07:29

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

Ty. 12.12.2008 07:30

Следуйте мантре TDD, хотя и в несколько ином контексте. Сделайте самое простое, что только может сработать. Требуется дисциплина, но оно того стоит.

tvanfosson 12.12.2008 07:33

cbo - Я согласен, но по крайней мере, свинья больше не выглядит такой противной. Тай - Правильным решением, вероятно, будет полная переработка, но очень часто это не то решение, для которого у нас есть ресурсы.

Chris Cudmore 12.12.2008 16:43

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

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

tvanfosson 12.12.2008 07:31

Код может быть «хорошо написанным», но поскольку он делает что-то сложное, для тех, кто никогда этого раньше не видел, он нуждается в большом количестве комментариев. Не бесполезные (например, переход по всем объектам в списке), а полезные (например, необходимо сбросить foo (), чтобы bar () не сработал позже).

Elie 12.12.2008 16:43

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

staticsan 19.12.2008 09:03

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

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

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

Ответ принят как подходящий

Ой! Похоже на то место, где я работаю.

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

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

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

В этом подкасте было несколько действительно действительно хороших советов. Спасибо за сообщение.

Ty. 12.12.2008 09:02

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

Chuck Conway 12.12.2008 09:37

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

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

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

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

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

Ооооо! Это требует больших усилий, но это должен быть идеальный способ сделать это. Престижность.

Jonathan C Dickinson 12.12.2008 11:01

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

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

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

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

Jonathan C Dickinson 12.12.2008 11:02

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