Подтвердить что ты не робот

Стратегия масштабного рефакторинга

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

Текущая структура тока в основном:

  • Большой шар грязи

Конечной целью является создание DDD-подобной структуры:

  • DAL
  • Модель домена
  • Уровень обслуживания
  • Модель представления
  • GUI

Итак, как бы вы атаковали проблему?

  • Большой взрыв
    • Определите структуру для конечного состояния и нажмите код в своем конечном доме.
  • Разделите и победите
    • Попробуйте отделить большой шар грязи до двух частей. Повторяйте до конца...
  • удушающий
4b9b3361

Ответ 1

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

Разделите и победите: это хорошо работает... если ваш мир имеет только две стороны. В реальном программном обеспечении вы должны одновременно завоевать так много фронтов, вы редко можете позволить себе жить в черно-белой фантазии.

Наверное, я использовал что-то вроде "Удушения" на протяжении большей части своей карьеры: постепенно превращал плохой старый код в блестящий новый код. Вот мой рецепт:

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

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

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

Недостаток: вам нужно много времени, и вы почувствуете разочарование, потому что часто прогресс будет казаться настолько медленным, пока "узел" не появится, и внезапно все начинает падать, как по волшебству.

Ответ 2

Я никогда не слышал о терминах "Приложение Strangler" - мне это нравится. Там, где это возможно, это всегда было бы хорошим подходом, это, безусловно, сводит к минимуму риск и является довольно прагматичным, отрываясь от большого здания по частям.

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

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

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

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

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

Для меня это зависит от ситуации.

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

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

BigBang очень рискован, так как у вас нет простого способа проверить, что обновленная система выполняет то же самое, что и старое.

Divide и Conquer менее рискованны, чем BigBang... но если его достаточно большая система, это может оказаться столь же проблематичным, как BigBang.

Ответ 7

Big bang/Big re-design/rewriting SW... или любые другие имена не будут работать для жизни SW. Причины таковы:

  • Вам все равно нужно поддерживать существующий SW (возможно) теми же ресурсами, которые у вас есть.

  • У вас, вероятно, нет требований к перезаписи. У вашего старого кода есть все требования, встроенные в него. Ни один из ваших инженеров не знает всех доменов SW и всех требований.

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

Ответ 8

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

Ответ 9

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