Я недавно начал новую работу, где я работаю над очень большим приложением (15M loc). В моей предыдущей работе у нас было такое же большое приложение, но (к лучшему или к худшему) мы использовали OSGi, что означало, что приложение было разбито на множество микросервисов, которые можно было независимо изменять, компилировать и развертывать. Новое приложение представляет собой всего лишь одну большую кодовую базу, возможно, с парой .dll.
Поэтому мне нужно изменить интерфейс этого класса, потому что это то, что мой босс попросил меня сделать. Первоначально они написали это с некоторыми допущениями, которые не очень хорошо обобщали, и какое-то время они избегали проблемы рефакторинга, потому что он так тесно связан. Я изменил интерфейс, и теперь есть более 25000 ошибок. Некоторые из ошибок в классах с важными звучащими именами, такими как «XYZPriceCalculator», которые на самом делене должен сломаться. Но я не могу запустить приложение, чтобы проверить, работает ли оно, пока все ошибки не будут устранены. И многие из модульных тестов либо напрямую ссылаются на этот интерфейс, либо связаны с базовыми классами, которые ссылаются на этот интерфейс, так что просто исправить их - довольно большая задача сама по себе. Кроме того, я не знаю, как все эти части сочетаются друг с другом, поэтому даже если бы я мог начать это, я не знаю, как это выглядело бы, если бы все было сломано.
Я никогда не сталкивался с такой проблемой на моей последней работе. Что я делаю?
источник
Ответы:
25000 ошибок в основном означает «не трогай это». Поменяй это обратно. Создайте новый класс с желаемым интерфейсом и медленно перемещайте потребителей этого класса в новый. В зависимости от языка, вы можете пометить старый класс как устаревший, что может вызвать всевозможные предупреждения компилятора, но фактически не нарушит вашу сборку.
К сожалению, такие вещи случаются в старых кодах. Вы ничего не можете с этим поделать, кроме как постепенно улучшать ситуацию. Когда вы создаете новые классы, убедитесь, что вы правильно протестировали их и создали их, используя принципы SOLID, чтобы их было легче менять в будущем.
источник
Разделяй и властвуй с помощью рефакторингов
Часто может помочь разбиение изменений, которые необходимо выполнить, на более мелкие этапы, поскольку затем вы можете выполнять большинство небольших этапов таким образом, чтобы это не нарушало программное обеспечение. Инструменты рефакторинга очень помогают в таких задачах.
Делить
Во-первых, определите наименьшие возможные изменения (с точки зрения логических изменений, а не с точки зрения измененного LoC), которые суммируют с изменением, которое вы хотите достичь. Особенно старайтесь изолировать шаги, которые являются чистыми рефакторингами и могут быть выполнены инструментами.
Покорять
В таких сложных случаях, как ваш, может иметь смысл выполнять один небольшой рефакторинг за раз, а затем оставить проблему в покое, чтобы все системы непрерывной интеграции могли проверить изменения, и, возможно, команда тестирования тоже посмотрела. Это подтверждает шаги, которые вы делаете.
Чтобы выполнить конкретный рефакторинг, вам абсолютно необходима поддержка инструмента для случая, когда у вас есть 25 000 сайтов вызовов того метода, который вы хотите изменить. Может быть, поиск и замена тоже работает, но в таком критическом случае я бы испугался этого.
пример
Например, в C # можно использовать Resharper для изменения сигнатуры метода. Если изменение достаточно простое, например, добавление нового параметра, вы можете указать, какое значение следует использовать на сайтах вызовов, которые в противном случае имели бы ошибку компиляции.
Тогда вы сразу же получите свободную от ошибок базу кода и сможете запустить все модульные тесты, которые пройдут, потому что это был только рефакторинг.
Как только сигнатура метода выглядит хорошо, вы можете перейти и заменить значения, которые Resharper добавил в качестве аргументов во вновь введенный параметр. Это больше не рефакторинг , но вы имеете безошибочную базу кода и можете запускать тесты после каждой изменяемой строки.
Иногда это не работает
Это очень полезный подход для таких случаев, как ваш, когда у вас много сайтов с вызовами. И у вас сейчас есть работающее программное обеспечение, так что может быть возможно выполнить небольшие шаги по рефакторингу, чтобы немного изменить подпись, а затем сделать другую.
К сожалению, это не будет работать, если изменение подписи слишком сложно и не может быть разбито на более мелкие изменения. Но это редко; разделив эту проблему на более мелкие проблемы , как правило , показывает , что это возможно.
источник
Уточните свою задачу у своего босса, чтобы помочь ему понять проблему и ваши потребности как профессионального разработчика программного обеспечения.
Если вы являетесь частью команды, найдите ведущего разработчика и спросите его совета.
Удачи.
источник
Не трогай это. Не совершай ничего.
Вместо этого сядьте на стул и закричите: так громко, как вы можете.
Ну, не совсем так, но спросите совета у любого из ваших старших коллег. Если у вас есть 25 000 ошибок, вы не исправляете ошибки, вы исправляете то, что вызвало ошибки. И старший коллега должен быть в состоянии посоветовать вам, как сделать изменение, которое хочет ваш начальник, без 25 000 ошибок. Существуют различные способы сделать это, но хороший способ зависит от вашей конкретной ситуации.
И, возможно, начальник сказал вашим старшим коллегам внести то же самое изменение, и они сказали «нет». Потому что они знали, что произойдет. Вот почему вам дали работу.
источник
Укоренившиеся API нельзя просто изменить. Если вам действительно нужно их изменить, аноатируйте и / или документируйте их как устаревшие (какими бы средствами ни позволял язык) и документируйте, какой API следует использовать вместо этого. Затем старый API можно постепенно свернуть ... возможно, очень медленно, в зависимости от вашего временного бюджета на рефакторинг.
источник
оценивать
Оцените, необходимо ли это изменение, или вы можете добавить новый метод и отказаться от другого.
Вперед
Если изменение необходимо; тогда необходим план миграции.
Первый шаг - ввести новый метод и заставить старый метод массировать свои аргументы, чтобы он мог вызывать новый. Это может потребовать жесткого программирования нескольких вещей; Все в порядке.
Это точка фиксации: убедитесь, что все тесты пройдены, зафиксированы, отправлены.
мигрировать
Занятая работа переносит всех вызывающих абонентов старого метода на новый. К счастью, это можно сделать постепенно благодаря экспедитору.
Так что давай; не стесняйтесь использовать инструменты, чтобы помочь (
sed
будучи самым основным, есть другие).Пометить старый метод как устаревший (с подсказкой перехода на новый метод); это поможет вам определить, забыли ли вы что-нибудь, и поможет, если коллега вводит вызов старого метода, пока вы работаете над этим.
Это точка фиксации (или, возможно, несколько точек фиксации): убедитесь, что все тесты пройдены, зафиксированы, отправлены.
Удалить
Через некоторое время (может быть, всего за день) просто удалите старый метод.
источник
sed
вероятно, плохая идея ... Что-то, что на самом деле «понимает» язык и не будет вносить непреднамеренные радикальные изменения, тем лучше..c_str()
например, вызов ) и ввести новые аргументы.sed
вроде работает, компилятор ловит свои проблемы потом.sed
(илиed
) может быть достаточно для такого рода вещей - при условии, что вы должным образом просматриваете различия перед тем, как совершить коммит.Если ваше изменение в сигнатуре метода является просто изменением имени, простое решение состоит в том, чтобы использовать инструменты для автоматизации изменения в 25 000 классов, которые ссылаются на данный метод.
Я предполагаю, что вы просто отредактировали код вручную, что привело ко всем ошибкам. Я также предполагаю, что вы знакомы с Java (видя вашу ссылку на OSGi), поэтому, например, в Eclipse (я не знаю, какую среду программирования вы используете, но в других средах есть аналогичные инструменты рефакторинга) вы можете использовать «Refactoring -> Rename» обновить все ссылки на метод, который должен оставить вас без ошибок.
Если вы вносите другие изменения в сигнатуру метода, а не просто переименовываете (изменяете число или типы параметров), вы можете использовать «Рефакторинг -> Изменить сигнатуру метода». Однако, скорее всего, вам придется быть более осторожным, как предполагают другие ответы. Кроме того, независимо от типа изменения, это все еще может быть довольно сложной задачей, фиксируя все эти изменения в загруженной кодовой базе.
источник
Здесь мой вклад.
Вы, вероятно, не знакомы с проектом и его «особенностями». Прежде чем вводить одну строку кода, важно ознакомиться с проектом. Поэтому сделайте откат изменений и начните с анализа кода . (По крайней мере, пострадавший)
Понимание существующего решения дает вам лучшее представление о том, куда вы попадаете. Контекстуализируйте решение и его важность.
Как отметил @Greg, вы должны иметь возможность протестировать существующий код, чтобы иметь действительную ссылку для сравнения (регрессионные тесты). Ваше решение должно быть в состоянии генерировать те же результаты, что и существующее. На данном этапе вас не волнует, верны ли результаты . Первая цель - это рефакторинг, а не исправление ошибок. Если в существующем решении написано «2 + 2 = 42», то и в вашем решении тоже должно быть. Если он не выбрасывает исключения, ваш тоже не должен. Если он возвращает нули, ваш тоже должен возвращать нули. И так далее. В противном случае вы будете подвергать риску 25 тыс. Строк кода.
Это ради ретро-совместимости.
Почему? Потому что сейчас это ваша уникальная гарантия успешного рефакторинга.
Срочно необходим способ гарантировать ретро-совместимость. Итак, вот ваш первый вызов. Изолировать компонент для модульного тестирования.
Имейте в виду, что эти 25 тысяч строк кода были сделаны с учетом возможных результатов существующего кода. Если вы не нарушите эту часть договора, то вы на полпути к окончательному решению. Если да, хорошо: да пребудет с тобой сила
После того, как вы разработали и внедрили новый «контракт», замените старый. Устаревай или убирай.
Я предложил оставить ошибки в одиночку, потому что рефакторинг и исправление ошибок - это разные задачи. Если вы попытаетесь взять их вместе, вы можете потерпеть неудачу в обоих случаях. Вы можете подумать, что нашли ошибки, однако они могут быть «функциями». Так что оставь их в покое (на минуту).
Мне кажется, что 25 тысяч строк кода достаточно для того, чтобы сосредоточиться только на одной задаче.
Как только ваша первая задача выполнена. Покажите эти ошибки / функции своему боссу.
Наконец, как сказал @Stephen:
источник
Проверь это.
Все остальные рекомендуют, как провести рефакторинг, чтобы не было никакого влияния. Но с таким количеством ошибок, даже если вы преуспели в рефакторинге всего с 10 строками кода (вы, вероятно, можете), вы оказали влияние на 25 000 потоков кода , даже если вам не нужно было их переписывать.
Итак, следующая вещь, которую нужно сделать, - убедиться, что ваш набор регрессионных тестов прошел в полете. А если у вас его нет, то сделайте тот, который будет. Добавление полного набора регрессионных тестов в ваш монолитный проект звучит скучно, но это хороший способ повысить уверенность в кандидатах на выпуск, а также ускорить их выпуск, если набор хорошо автоматизирован.
источник