Рефакторинг большой функции C ++ - PullRequest
4 голосов
/ 06 мая 2009

На работе у нас есть устаревший процесс, написанный на Visual C ++, который в основном состоит из одной 5000-строчной функции. По сути, программа - это всего лишь одна большая инструкция case с похожим вырезанным и вставленным кодом, обрабатывающая достаточное количество логики для case. Очевидно, что мы хотели бы реорганизовать этот код, чтобы выделить эти случаи в отдельные функции (или объекты) и устранить любой вырезанный и вставленный код.

У меня вопрос: есть ли какие-либо предложения для проведения рефакторинга такого размера? Есть ли автоматизированные инструменты, которые могли бы упростить процесс?

Ответы [ 9 ]

6 голосов
/ 06 мая 2009

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

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

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

3 голосов
/ 06 мая 2009

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

3 голосов
/ 06 мая 2009

Несколько предложений:

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

Инструменты рефакторинга могут автоматически выполнять такие операции, как извлечение части функции в новую функцию. Eclipse CDT , например, может сделать это, и это бесплатно, и он может редактировать код, который поддерживается в других IDE. Это не всегда работает, но когда это работает, действительно удивительно наблюдать, как IDE разделяет метод из тысячи строк, выделяя то, что вы хотите, и правильно идентифицируя каждую переменную, которую нужно передать в качестве нового параметра. к вашему новому методу ... Доступны другие инструменты рефакторинга, такие как Refactor! Pro (доступна бесплатная версия), но я ими не пользовался.

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

2 голосов
/ 06 мая 2009

Попробуйте Visual AssistX на www.wholetomato.com . Он интегрируется напрямую с любой версией Visual Studio от VS6 и выше. Он включает в себя множество отличных возможностей для разработки, но вам нужна функция рефакторинга. Вы можете увидеть эту функцию здесь . Это стоит денег, но я считаю это «секретным оружием» при разработке с Visual Studio.

0 голосов
/ 05 мая 2012

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

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

0 голосов
/ 06 мая 2009

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

В настоящий момент все они потерпят неудачу.

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

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

Каждая из новых функций также должна иметь свои собственные модульные тесты, кстати.

0 голосов
/ 06 мая 2009
  1. Не пытайтесь делать все сразу.
  2. определить вероятную цель рефакторинга. Будьте как можно более узкими.
  3. написать тесты для проверки правильности работы этого фрагмента кода.
  4. Как только все ваши тесты пройдут или не пройдут, потому что исходная функция действительно содержит эту ошибку, выполните рефакторинг этого бита.
  5. Убедитесь, что все ваши тесты все еще проходят.
  6. GOTO 2.
0 голосов
/ 06 мая 2009

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

0 голосов
/ 06 мая 2009

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

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