Я изменил одну подпись метода и теперь имеет более 25 000 ошибок. Что теперь?

Недавно я начал новую работу, когда работаю над очень большим приложением (15M loc). В моей предыдущей работе у нас было такое же большое приложение, но (к лучшему или к худшему) мы использовали OSGi, что означало, что приложение было разбито на множество микросервисов, которые могут быть независимо изменены, скомпилированы и развернуты. Новое приложение представляет собой лишь одну большую базу кода, возможно, пару DLL.

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

Я никогда не сталкивался с такой проблемой на моей последней работе. Что мне делать?

166 голосов | спросил user788497 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 05:01:46 +0300 2016, 05:01:46

9 ответов


348

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

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

ответил Stephen 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 05:35:04 +0300 2016, 05:35:04
80

Разделить и перехватить с помощью рефакторинга

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

Деление

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

властвуй

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

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

<сильный> Пример

В C #, например, можно использовать Resharper до изменить подпись метода. Если изменение достаточно простое, например, добавив новый параметр , вы можете указать, какое значение следует использовать на сайтах-узлах, которые в противном случае имели бы ошибку компиляции.

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

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

Иногда это не работает

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

К сожалению, это не сработает, если изменение подписи слишком сложное и не может быть разбито на более мелкие изменения. Но это редко; разбиение проблемы на более мелкие проблемы обычно показывает, что возможно .

ответил theDmi 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 10:37:29 +0300 2016, 10:37:29
36

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

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

Удачи.

ответил mmehl 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 10:53:11 +0300 2016, 10:53:11
28

Не трогайте его. Не совершайте ничего.

Вместо этого сядьте на стул и кричите «Heeeeelp !!!!!» как можно громче.

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

И может быть, босс сказал своим старшим коллегам сделать то же самое, и они сказали «нет». Потому что они знали, что произойдет. Вот почему вам дали работу.

ответил gnasher729 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 12:02:31 +0300 2016, 12:02:31
22

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

ответил Kevin Krumwiede 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 05:29:31 +0300 2016, 05:29:31
10

<сильный> Оценка

Оцените, требуется ли это изменение, или вы можете добавить новый метод и осудить другое.

<сильный> Вперед

Если изменение необходимо; то необходим план миграции.

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

Это точка фиксации: проверьте, чтобы все тесты проходили, фиксировали, нажимали.

<сильный> Перенести

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

Так что вперед; не стесняйтесь использовать инструменты для помощи ( sed , являющийся самым основным, есть и другие).

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

Это точка фиксации (или, возможно, несколько точек фиксации): проверьте, чтобы все тесты проходили, фиксировали, нажимали.

<сильный> Удалить

По прошествии некоторого времени (возможно, всего за день) просто удалите старый метод.

ответил Matthieu M. 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 12:46:44 +0300 2016, 12:46:44
8

Если ваше изменение подписи метода - это просто изменение имени, простым решением является использование инструментов для автоматизации изменения в 25 000 классов, которые ссылаются на данный метод.

Я предполагаю, что вы просто отредактировали код вручную, что вызвало все ошибки. Я также предполагаю, что вы знакомы с Java (см. Вашу ссылку на OSGi), так, например, в Eclipse (я не знаю, какую среду программирования вы используете, а в других средах аналогичные инструменты рефакторинга) вы можете использовать «Refactoring -> Rename «обновить все ссылки на метод, который должен оставить вас без ошибок.

Если вы делаете другие изменения в сигнатуре метода, чем просто переименование (изменение числа или типов параметров), вы можете использовать «Рефакторинг -> Изменить подпись метода». Однако, скорее всего, вам придется быть более осторожными, как предлагают другие ответы. Кроме того, независимо от типа изменения, это может быть довольно сложной задачей, выполняющей все эти изменения в загруженной кодовой базе.

ответил Mikkel 4 52016vEurope/Moscow11bEurope/MoscowFri, 04 Nov 2016 12:16:46 +0300 2016, 12:16:46
6

Вот мой вклад.

  

Недавно я начал новую работу, когда я работаю над очень большим   приложение (15M строк кода).

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

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

Как отметил @Greg, вы должны иметь возможность протестировать существующий код, чтобы иметь действительную ссылку для сравнения с (регрессионные тесты). Ваше решение должно быть способно генерировать те же самые результаты , что и существующее. На этом этапе не заботятся о правильности результатов . Первой целью является рефакторинг, а не исправление ошибок. Если существующее решение говорит «2 + 2 = 42», ваше решение тоже должно быть. Если он не бросает исключения, ваш тоже не должен. Если он возвращает nulls, ваш должен также возвращать значения null. И так далее. В противном случае вы будете подвергать риску 25k строк кода.

Это ради ретро-совместимости.

Почему? Потому что прямо сейчас, это ваша уникальная гарантия успешного рефакторинга.

  

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

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

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

Как только вы разработали и внедрили новый «контракт», замените старый. Измените его или вытащите.

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

25k строк кода мне кажутся достаточно, чтобы сосредоточить внимание только на одной задаче.

Как только ваша первая задача будет выполнена. Откройте эти ошибки /функции своему боссу.

Наконец, как сказал @Stephen:

  

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

ответил Laiv 5 62016vEurope/Moscow11bEurope/MoscowSat, 05 Nov 2016 19:22:13 +0300 2016, 19:22:13
5

Проверить его.

Все остальные рекомендуют рефакторинг, чтобы иметь мало влияния. Но с такими многочисленными ошибками, даже если вам удастся реорганизовать всего 10 строк кода (возможно, вы можете), то вы затронули 25 000 потоков кода , даже если вам не нужно переписывать их.

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

ответил Greg 5 62016vEurope/Moscow11bEurope/MoscowSat, 05 Nov 2016 00:17:28 +0300 2016, 00:17:28

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132