Может ли кто-нибудь объяснить плюсы удаления (или сохранения) неиспользуемого кода?

102

Я много раз слышал, что неиспользуемый код нужно удалить из проекта. Однако мне непонятно «почему?».

Мои советы не удалять:

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

Может ли кто-нибудь объяснить плюсы удаления (или сохранения) неиспользуемого кода?

Алексей Турбин
источник
16
Закомментированный код также не должен принадлежать кодовой базе.
leppie
27
Потому что у нас есть контроль версий. Если нам когда-нибудь понадобится обратиться к старым версиям кода, мы можем просто просмотреть историю.
armandino 01
1
Кстати, ссылаться на контроль версий может быть сложно, когда проект большой, а некоторые файлы имеют> 200 ревизий
Алекс Турбин
22
@AlexStamper, если ваши инструменты не позволяют вам легко просматривать предыдущие версии вашего кода, решением будет получить лучшие инструменты, а не добавлять шум в исходный код.
utnapistim 05
1
У Software Engineering есть очень похожий вопрос .
davidvandebunte

Ответы:

181

Вот несколько причин, по которым неиспользуемый код следует удалить:

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

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

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

  • Со временем в базу кода добавляется все больше и больше старого неиспользуемого кода. Это увеличивает путаницу, возможное недопонимание и административные издержки.

  • Шансы на то, что неиспользованный код когда-либо снова будет использоваться, очень маловероятны. Со временем вероятность повторного использования уменьшается. Если код должен быть удален и считается достаточно важным, тогда код можно разделить и задокументировать.

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

подозреваемый
источник
26
Недавно я до смерти напугал меня из-за того, что смотрел на неиспользуемый код (и не понимал, что он не использовался). Неиспользуемый код должен быть исключен из существования!
leppie
1
хорошие моменты, спасибо. Мои коллеги тоже заявили о некоторых из них
Алексей Турбин
Отличный ответ. Я хотел бы сослаться на подобные аргументы в своей магистерской диссертации, но не могу найти подходящий источник (книгу, статью и т. Д.). У вас есть зацепки?
Йонас Винклер
3
Мне было бы очень интересно узнать, почему вы проголосовали против.
Suspectus
1
Еще один момент: если старый код понадобится снова, в большинстве проектов в настоящее время используется SCM, и код можно получить из него снова (иногда с некоторым поиском, правда, но, как ясно указано в ответе, вероятность неиспользованного кода будет потребность снова уменьшается с возрастом).
Чоп
31

@suspectus отлично справился с описанием причин удаления кода; Я хотел бы обратиться к вашим отдельным пунктам по сохранению кода.

  • Код уже написан, и усилия потрачены

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

  • Код может быть протестирован в синтетической и реальной среде

Извините, я не понимаю, что вы имеете в виду.

  • Если хорошо организована (сгруппированы, отдельные пакеты, слабо связаны и т. Д.), Это не мешает вам в целом анализировать код или рефакторинг.

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

  • Код может быть использован в будущем

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

  • При удалении автор может чувствовать себя неуютно

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

Карл Манастер
источник
17

Разве не достаточно сложно взять код и выяснить его намерение, но теперь вы должны выяснить, какие части не используются?

Кенни
источник
14

Код уже написан, и усилия потрачены

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

Код может быть протестирован в синтетической и реальной среде

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

Если хорошо организована (сгруппированы, отдельные пакеты, слабо связаны и т. Д.), Это не мешает вам в целом анализировать код или рефакторинг.

Не так. Все ваши инструменты (система контроля версий, статический анализ, средство извлечения документации, компилятор и т. Д.) Будут работать медленнее, потому что им нужно обрабатывать больше данных (и большая или меньшая часть этих данных является шумом).

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

Вы вносите шум во вводимые вами инструменты и надеетесь, что они правильно с ним справятся.

Что, если ваш инструмент статического анализа вычисляет соотношение комментариев / кода? Вы просто напортачили с чем-то, что было актуально до вчерашнего дня (или всякий раз, когда код был прокомментирован).

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

Код может быть использован в будущем

Если это так, вы найдете его в выбранном вашей командой SCM.

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

При удалении автор может чувствовать себя неуютно

Так?

Вы (я полагаю) целая команда разработчиков, которой платят за создание лучшего программного обеспечения, которое вы умеете делать, а не «лучшего программного обеспечения, которое вы умеете делать, не задевая чувства X».

Это часть программирования, большая часть написанного кода в конечном итоге будет отброшена; например, Джоэл Спольски в какой-то момент сказал, что для его компании примерно 2% написанного кода предназначено для производства.

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

Изменить: я видел одну вескую причину оставить закомментированный код в источнике, и это очень конкретный случай: когда код написан в странной / неинтуитивной форме, а чистый способ его переписывания не работают по очень тонкой причине. Это также следует применять только после того, как была предпринята повторная попытка исправить проблему, и каждый раз при повторной попытке повторного появления одного и того же дефекта. В таком случае вы должны добавить прокомментированный интуитивно понятный код в качестве комментария и объяснить, почему он не работает (чтобы будущие разработчики не пытались повторить то же изменение снова):

// note by <author>: the X parameter here should normally
// be a reference:
// void teleport(dinosaur& X);
// but that would require that we raise another dinosaur and
// kill it every twelve hours
// as such, the parameter is passed by value
void teleport(dinosaur X);
утнапистим
источник
10

Мертвый код загрязняет ваш код

Мертвый код снижает понятность и читаемость.

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

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

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

Джимми
источник
10
  • Страх . Это заставляет команду больше волноваться и меньше производить. Степень страха растет экспоненциально, когда вводится больше мертвого кода. «Мы не знаем, используется ли этот бит, поэтому не осмеливаемся удалить его или прикоснуться к нему».
  • Стремительные перемены . Если что-то, что нужно изменить повсюду в системе, также существует в мертвом коде, вы меняете это? Очень сложно понять, не используется ли он где-то точно, так что это всегда риск. И даже если это ничего не сломает, будет ли вообще работать мертвый код, если его вернут к использованию после этого изменения?

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

  • Умственная нагрузка . Каждый раз, когда вам нужно думать о том, используется ли что-то или нужно ли что-то делать с мертвым кодом, это требует некоторой силы вашего мозга.
  • Погоня за дикими гусями . «Мне нужен пример использования Foobar. О, он находится в этих местах в кодовой базе. Я проверю первое попадание и выясню, где оно находится в пользовательском интерфейсе. Хм ... Нигде не могу найти».
  • Завышенные отчеты (например, сколько строк кода, классов, подпрограмм, изменений). Искажает видимость проекта и решения о том, над какими частями кодовой базы следует работать, а также оценки будущих проектов.
  • Ослабление доверия к кодовой базе . Это может привести к тому, что больше времени будет потрачено на избыточные задачи, и нарушит поток использования кодовой базы. Разработчикам, возможно, придется очень внимательно проверить, что все, что они используют, будет работать так, как они думают.

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

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

Хейкки Наски
источник
4
  • Неиспользуемый код - это больше места для поиска, которое вы можете прочитать, и все, что обычно сканирует ваш код. Например, компилятор, IDE, поиск в файле, отладка, статический анализ, дополнительные сведения для просмотра, включение файлов, извлечение из VCS и т. Д. Это замедляет эти процессы и добавляет значительный шум.
  • Неиспользуемый код - это не всегда мертвый код. Он может выполняться при определенных обстоятельствах. Это может не только предложить вектор ошибок и проблем с производительностью, но также может быть проблемой безопасности. Что касается производительности, это может проявляться неожиданным образом, например, при увеличении количества загрузок.
  • Неиспользованный код порождает неиспользуемый код. Если вы удалите вызов функции, а затем выполните поиск вариантов использования этой функции, чтобы увидеть, нужна ли она еще, вы можете увидеть совпадение с предыдущим неиспользованным кодом и предположить, что вы можете его сохранить. Чем больше у вас неиспользуемого кода, тем больше переходов нужно для определения того, не используется ли код.
  • Неиспользуемый код по-прежнему часто приходится поддерживать. Допустим, A и B зависят от C. Из них B не используется. Вы меняете C, а затем B не компилируете, потому что вы удалили член из структуры в C, который требовался B, теперь вам нужно исправить B или активно удалить его из компиляции. Вы должны были просто удалить его.

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

В ответ на ваши баллы ...

  • Код уже написан, и усилия потрачены

Но часто его нужно поддерживать. Он также будет отображаться в таких вещах, как поиск в файле.

  • Код может быть протестирован в синтетической и реальной среде

Я не уверен, что вы имеете в виду под этим. Думаю, он такой же, как и предыдущий. Вы имеете в виду, что код уже протестирован, и его очистка может означать, что он нуждается в повторном тестировании. Это затраты, которые обычно окупаются, потому что они окупаются в 90% случаев, и во избежание того, чтобы их нужно было очистить перед запуском в производство. Практически весь код состоит из двух итераций: пусть он работает, исправляется. Причина, по которой нужно тестировать дважды, заключается в том, что кто-то пропустил последний шаг. Если ваш код также слишком дорог для проверки, прочитайте diff, test (что, вероятно, будет, если он запутан с большим количеством неиспользуемого кода) и т.д., тогда это еще одна проблема.

  • Если хорошо организована (сгруппированы, отдельные пакеты, слабо связаны и т. Д.), Это не мешает вам в целом анализировать код или рефакторинг.

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

  • Код может быть использован в будущем

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

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

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

  • При удалении автор может чувствовать себя неуютно

Это проблема автора. С одной стороны, эгоистично оставлять множество неиспользуемого кода для других. С другой стороны, если автор ставит свои чувства выше качества кода, ему, вероятно, не следует писать код. Вы идете по дороге с этим: вы не можете исправить их код, когда он сломан, потому что это обидит их чувства. Если кто-то привязан к коду просто потому, что он его, а не потому, что он хорош, это плохой знак. Автор должен быть доволен чисткой своего кода. Это как если бы кто-то вынул за вас ваш мусор и выбросил его в мусорное ведро.

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

jgmjgm
источник
3

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

Анкур
источник
3

Этому обсуждению несколько лет, но я только что столкнулся с ним ...

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

RonE
источник
2

Я думаю, что у вас может быть два случая: - код приложения: если он не используется, возможно, он не тестировался и не поддерживался с течением времени, может быть, вы можете перейти во «внутренний репозиторий кода» - код API: если вы пишете библиотеку, то IMHO это лучший выбор для его поддержки, но внутри вашего активного процесса разработки

Антонелло Пазелла
источник
2

Вы уверены, что код не используется?

Недостаточно проверить, что код все еще компилируется. В C ++, если вы удалите «неиспользуемый» неявно определенный метод, как operator=будто вы не собираетесь получить ошибку компилятора, класс просто незаметно начнет использовать (потенциально неправильную) реализацию по умолчанию. В Java или C # код можно использовать через отражение. В объектно-ориентированных языках наследование может играть роль (теперь можно вызвать базовый класс). Практически на любом языке могла быть взята другая перегруженная функция.

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

Агрессивно удаляйте неиспользуемый код

Вы платите за поддержку кода:

  • Исправление неработающих сборок (время разработки). Недавно у нас была сложная цепочка #includeизменений, когда мы добавили новую перегрузку в неиспользуемый код, что привело к разумной головной боли для каждого инженера в команде из десятков разработчиков.
  • В машинных ресурсах на тестах (при условии, что у вас есть непрерывные сборки с самотестированием). Моя команда недавно просмотрела все наши самые медленные тесты, и многие из них были поверх неиспользуемого кода. Инженеры, выполняющие тесты локально или в рамках непрерывной интеграции, ждут тестов поверх неиспользуемого кода.
  • С точки зрения читабельности (снова время инженеров). Ваши файлы заголовков представляют собой API. Если они включают в себя функции, которые никто не хотел бы использовать, но каждый должен читать, кривая обучения вашему коду будет намного сложнее.
  • В поисках кода (снова инженерное время). Вы бы очистили свой дом, жесткий диск или Google Диск? Чем больше вы выполняете поиск по домену, тем важнее, чтобы он имел релевантный контент, чтобы избежать ложных срабатываний (или вы используете более сложный поиск, такой как поисковая система в Интернете).

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

Давидвандебунте
источник