Стратегия масштабного рефакторинга - PullRequest
22 голосов
/ 01 декабря 2008

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

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

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

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

  • DAL
  • Доменная модель
  • Сервисный уровень
  • Презентация модели
  • GUI

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

  • Большой взрыв
    • Определите структуру для конечного состояния и отправьте код в окончательный вариант.
  • Разделяй и властвуй
    • Попробуйте разделить большой шарик грязи на две части. Повторяйте, пока не закончите ...
  • душит

Ответы [ 9 ]

15 голосов
/ 01 декабря 2008

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

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

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

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

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

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

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

6 голосов
/ 01 декабря 2008

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

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

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

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

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

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

4 голосов
/ 02 декабря 2010

Я наткнулся на «метод Микадо», который кажется многообещающим для решения проблем такого рода.

http://mikadomethod.wordpress.com/

Существует также разговор о методе Микадо из Øredev 2010.

http://oredev.org/2010/sessions/large-scale-refactorings-using-the-mikado-method

2 голосов
/ 17 сентября 2015

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

  • Вам все еще нужно поддерживать существующее ПО с (вероятно) теми же ресурсами, что и у вас.

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

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

1 голос
/ 01 декабря 2008

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

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

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

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

Разделяй и властвуй менее рискованно, чем BigBang ... но если это достаточно большая система, она может оказаться такой же проблематичной, как BigBang.

1 голос
/ 01 декабря 2008

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

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

1 голос
/ 01 декабря 2008

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

0 голосов
/ 01 декабря 2008

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

0 голосов
/ 01 декабря 2008

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

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