Индустрия программного обеспечения. Как эффективно работать с устаревшим и чистым кодом?

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

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

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

В таких ситуациях я рекомендую вам выслушать, прежде чем судить. Почему ваши коллеги предпочитают, например, собственный класс строк стандартным строкам? Почему было принято такое решение или это было формальное решение? Каковы плюсы и минусы перехода на стандартные строки? Сколько времени потребуется, чтобы переключиться? и т. д.
Что бы вы ни делали, не проводите рефакторинг старого кода, если вы полностью не понимаете его и вам не поручено провести его рефакторинг.
@jcmack Насколько мне известно, ситуации, связанные с пользовательскими классами для аналогов STL, возникали из-за того, что их не существовало, или потому, что в то время они были слишком медленными (мы построили системы реального времени). Мы небольшая компания, поэтому переход на пользовательские классы просто нереалистичен; Я бы предположил, что на рефакторинг всего уйдет больше года. Мне прямо сказали, что большинству наших разработчиков не нравится наш пользовательский класс строк, но они сохраняются из-за проблем совместимости и сроков. Моя трудность заключается в том, чтобы сбалансировать устаревший код и современный cpp, который субъективно более удобочитаем и удобен в сопровождении.
@JonSG Я не предлагаю рефакторить старый код. Я хотел бы найти способ найти баланс между более эффективной работой с читаемым кодом и сохранением устаревших функций.
@MichaelChoi Я полностью понимаю. Очень важно работать в рамках существующей структуры управления в вашей компании, чтобы выдвинуть инициативу, подобную этой. Как менеджер или высшее руководство, я определенно хотел бы знать сроки, количество необходимых людей, плюсы и минусы и план миграции/развертывания. С таким большим усилием, как год, я бы определенно порекомендовал постепенную стратегию, если это возможно.
В таких случаях вы иногда можете определить лучший путь к чему-то в будущем. Вы сохраняете рабочий код, но будущие изменения в изолированной системе могут быть обновлены. Конечно, для этого требуются функции пользовательского кода, аналогичные функциям стандартного или улучшенного метода, что не всегда так, если пользовательский код имеет проблемы с покрытием кода.
«У меня большие трудности с написанием программного обеспечения, которое требует так много обслуживания». К сожалению, это предложение эквивалентно высказыванию «У меня проблемы с программированием». Хорошо это или плохо, но вы просто описываете абсолютно нормальный рабочий день «инженера-программиста».
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что он касается программирования, а не навигации по рабочему месту.

Ответы (3)

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

С учетом сказанного, я бы порекомендовал высказываться о ваших идеях по улучшению. Возможно, никто и никогда не позволит переписать все это целиком. Но стандарты кодирования подлежат постоянному совершенствованию, и здоровая команда это понимает. Как насчет того, чтобы сделать презентацию о том, почему векторы лучше, чем массивы? Или начать дискуссию в командном чате или по электронной почте о целесообразности пользовательских реализаций для стандартных объектов? Конечно, было бы неплохо поделиться парой ссылок, скажем, на сообщения в блогах от громких имен в отрасли, чтобы укрепить свои позиции. И когда после этих обсуждений у вас будет хоть какой-то консенсус, проявите инициативу и создайте опрос о принятии этой идеи в качестве стандарта с этого момента. Даже если это не будет принято, вы узнаете то, что вам неизвестно в данный момент.

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

И еще одна ситуация, чтобы показать, что изменения более возможны, чем вы думаете. В деловом мире нам нужно говорить деловыми терминами. Рефакторинг ради самого рефакторинга не приносит никакой пользы, но когда вы сможете продемонстрировать, как это изменение повлияет на результаты, вы, скорее всего, получите зеленый свет на любой запрос. Иногда поддержка одной конкретной части кода является болезненной, в то время как разумные усилия по доработке значительно ускорят ее. Я призываю вас говорить об этом, а не бороться с этим. Приведите некоторые цифры, сделайте приблизительные оценки того, сколько времени займет улучшение функции с рефакторингом и без него. Продайте эту работу своему техническому руководителю/менеджеру по продукту/другому соответствующему влиятельному лицу по мере необходимости, и выбор будет для них очевидным. После этого успеха "внезапно" вы Вы обнаружите, что возглавили проект по превращению этой части кодовой базы в место, где вступают в игру современные стандарты кодирования. Действуй! Просто убедитесь, что у вас есть тесты для всех критических функций, прежде чем вы начнете! ;)

Удачи, Майкл.

Отличный ответ (+1)! Кроме того, помните о канонической книге « Эффективная работа с унаследованным кодом » - ее необходимо прочитать всем, кто находится в положении ОП.
@vladimino Я ценю продуманный ответ. Думаю, попробую применить на практике. На самом деле я только начинаю свой первый год профессионального обучения, поэтому я определенно новичок и определенно не полностью понимаю применение пользовательских классов нашей компании. При этом, исходя из опыта, который у меня есть, я могу сказать, какие классы показывают возраст, и я думаю, что последую вашему совету относительно очень небольших постепенных изменений.

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

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

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

Дело в том, что ваш коллега мог написать библиотеки, которые проверяют условия и границы. Сначала я бы спросил напрямую, почему бы не использовать библиотечную функцию X в отличие от внутренних методов. Посмотрите, что они говорят.

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

В дополнение к отличному ответу vladimino, вы могли бы предложить своему боссу провести некоторые оценки (возможно, полдня в неделю).

Метрики могут быть:

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

Таким образом, вы можете построить дело с цифрами, если рефакторинг добавит ценность для бизнеса. А может и нет.

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