Maven и рефакторинг в нескольких проектах

В настоящее время я пытаюсь найти подходящий рабочий процесс для выполнения рефакторинга в нескольких проектах Maven, но не могу найти никакого удовлетворительного решения.

Предположим, есть три проекта. Один проект называется общим и два зависимых проекта - app1 и app2. Каждый в отдельном репозитории Git.

Теперь предположим, что общий метод, называемый StringUtils.trim(), должен быть переименован в StringUtils.getTrimed(). Поскольку этот метод используется app1 и app2, эти проекты также необходимо адаптировать.

Теперь вопрос в том, каков правильный рабочий процесс для предоставления этой модификации команде разработчиков. Учитывая эту ситуацию: команда из около 10 разработчиков с центральным сервером SCM и центральным сервером репозитория Maven для размещения артефактов.

Возможные рабочие процессы:

  1. Просто зафиксируйте изменения в SCM (для всех трех проектов) -> Проблема: разработчики, работающие, например, с app1, вероятно, не имеют проверенного общего проекта, но используют двоичный файл с центрального сервера артефактов. Когда они получат новейшую версию app1 из SCM, их сборка будет прервана. ПЛОХОЙ!

  2. В дополнение к 1 измените зависимость app1, чтобы она указала на общую версию SNAPSHOT. -> Проблема: когда разработчики, работающие над app1, выбирают самую последнюю версию из SCM, они, вероятно, не получат последний общий SNAPSHOT, если для политики обновления установлено значение DAILY (по умолчанию). ПЛОХОЙ!

  3. В дополнение к 2 измените политику обновления для SNAPSHOTS на ВСЕГДА. -> Проблема: теперь разработчики app1 получат последний общий SNAPSHOT, и все в порядке, но только если SNAPSHOT развернут на сервере артефактов, прежде чем я внесу изменения в app1! Кроме того, существует промежуток времени между развертыванием общего проекта на сервере артефактов и моей фиксацией app1 в SCM. Если разработчики получат последний общий SNAPSHOT, он будет несовместим с текущей версией app1 в SCM, поскольку я еще не внес изменения в app1. ПЛОХОЙ!

Единственное работоспособное решение, которое я могу придумать, - это пропустить механизм SNAPSHOT и работать с версиями. Вот рабочий процесс:

  • После изменения трех проектов локально на моей машине (перед любой фиксацией) увеличьте версию common с скажем 1.0 до 1.1.
  • Зафиксируйте общий для SCM и разверните его на сервере артефактов.
  • Только после завершения развертывания измените зависимости в приложениях app1 и app2, чтобы они указывали на новую версию common и фиксировали app1 и app2.

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

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

4 ответа

Я бы порекомендовал вам инструмент с открытым исходным кодом, как Sonar (sonarsource.org)

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

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

Я бы посоветовал вам хранить имена методов вашего интерфейса в максимально возможной степени, с именем должно быть что-то ужасно неправильное, чтобы оно могло измениться (имя указывает, что оно делает то, чего не делает, или наоборот)). Желание изменить "trim()" на "getTrimmed()" не является достаточной причиной для этого.

Итак, мое предложение будет таким:

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

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

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