Как перенести некрасивый и недокументированный код VB6 в .NET - PullRequest
23 голосов
/ 20 января 2010

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

Я должен сказать, что качество, структура и архитектура Кодекса - это просто кошмар. Есть 2 больших проекта: Nr.1 с 40 формами, 40 модулями и несколькими файлами классов, этот EXE является своего рода «базовой системой». Nr.2 с 80 формами, 20 модулями и несколькими файлами классов, этот EXE вызывает функции из «базовой системы». Затем есть ~ 10 других проектов с графическим интерфейсом (1-3 формы каждый) и еще 90 проектов без графического интерфейса, большинство из них EXE-файлы, некоторые библиотеки DLL. Библиотеки написаны на C, C ++ и VB6.

Кодекс эволюционировал с 10 лет и написан в основном одним (плохим) разработчиком за один раз.

  • Функции с 500 строками (и более) очень распространены.
  • 90% компонентов графического интерфейса имеют имя text1, command2 (1),…
  • копирование и вставка повсюду e. г. был скопирован проект EXE-файла (без графического интерфейса) с 5000 строками кода, и единственное изменение в копии состояло в том, что он отправлял файлы по почте вместо FTP (есть еще 2 копии этого же проекта).
  • Однажды у меня была небольшая форма (15 полей), где я должен был решить небольшую проблему (обычно максимум полчаса), каждый раз, когда я что-то менял, это либо не работало, либо приводило к новым ошибкам в форма. Через 2 дня я решил полностью переписать форму, и из ~ 20 операторов SQL в старой форме только 2 выжили в новой.
  • даже не спрашивайте о комментариях в коде ...

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

Мои параметры

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

2) Переносить код в VB.NET / C # Миграция основных проектов в первую очередь, я уже протестировал это и получил ~ 2000 комментариев по обновлению от Project Nr.1, большинство из которых, например Screen.MousePointer, были изменены, функции с вариантами возвращаемых значений и так далее. Моя идея здесь заключается в том, чтобы после преобразования создать классы для абстракции БД, изменить код для использования этих классов и выполнить рефакторинг, перенести и изменить другие проекты, а когда весь код использует классы БД, измените структуру БД.

3) Рефакторинг кода в VB6 всякий раз, когда мне все равно нужно что-то там менять (я уже делаю это частично), а в какой-то момент рефакторинг также и остальное. Таким образом, легче увидеть исходную функциональность, потому что это оригинальный код, и когда есть ошибки, очевидно, что они не могут быть результатами миграции. Когда код подвергается рефакторингу (я предполагаю, что он будет на 50-75% меньше), его будет проще перенести в .NET Затем измените структуру БД (а затем выполните еще один раунд рефакторинга…).

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

Мой вопрос: у кого есть опыт / советы по переносу плохого, уродливого кода? Какие варианты вы бы предложили?

Ответы [ 9 ]

20 голосов
/ 20 января 2010

Мне пришлось пройти через то же самое (приложение Massive VB6 без документации и ужасного кода.). Единственный безопасный и разумный путь, по которому вы можете пойти, - это номер 3. Чтобы что-то улучшить, вы должны сначала это понять. Если вы выберете маршрут 1 или 2, вы гарантированно останетесь в ужасном беспорядке.

Не забудьте всегда помнить о том, что вашей конечной целью является полная миграция на .NET. В процессе рефакторинга подумайте, как будет выглядеть ужасная поддержка OO в VB6 в VB.NET или C #. Если возможно, измените код, чтобы облегчить миграцию.

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

Самое важное, что вам нужно помнить, это не быть ковбоем.

  1. Написать тесты для модуля.
  2. Рефакторинг модуля.
  3. Проверка модуля.
  4. Выпустите ваше приложение.
  5. GOTO 1
11 голосов
/ 20 января 2010

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

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

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

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

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

10 голосов
/ 20 января 2010

Опытный аналогичный перенос 14-летнего кода на VS2008

Вот несколько советов:

  1. Удалить зависимости от сторонних компонентов.
  2. Рассмотрим поэтапную миграцию, например используя обратное взаимодействие.
  3. Цвета и шрифты должны обрабатываться вручную.
  4. Остерегайтесь неинициализированных объектов в массивах после перехода на .NET
  5. Заменить при ошибке на Try Catch
  6. При необходимости используйте пространство имен Microsoft.VisualBasic.Compatibility.VB6.
  7. Продолжайте рефакторинг до минимума, пока весь код не преобразуется в .NET
  8. Следите за ненулевыми массивами в коде VB6.
  9. Рефакторинг (минимальный) вашего кода в VB6, чтобы он мог пройти через мастер преобразования кода.
  10. Остерегайтесь 1 управления VB6 на основе, например. ListView
  11. Используйте синхронизацию, чтобы избежать проблем с потоками.
  12. Если вы выполняете рефакторинг сабвуфера вручную, будьте осторожны с изменениями размеров типов данных, особенно если вы работаете с файловым вводом-выводом.

Есть компания, которая может помочь вам во всем процессе (хотя мы не использовали их) http://www.vbmigration.com/

6 голосов
/ 21 января 2010

вы проделали большую работу, сформулировав этот вопрос. Спасибо за вопрос! И спасибо сообществу stackoverflow за публикацию вдумчивых ответов (как обычно).

Если это довольно большая кодовая база, и она звучит так (50-100 взаимосвязанных VBP, 200-500K LOC), то вам следует подумать об инвестировании в инструменты миграции. Рассмотрим эту аналогию: если у вас было большое количество данных для преобразования, даже если исходные данные были грязными и сильно отличались от желаемого формата, вы бы использовали инструменты. Если кто-то посоветует вам просто повторно ввести данные или даже выполнить черновое преобразование, а затем исправить это вручную, вы подумали бы, что они чокнутые. Кроме того, с 120 формами приложение звучит так, как будто оно предоставляет довольно значительный объем бизнес-функций. Эта бизнес-функциональность появилась в течение многих лет использования, и, нравится нам это или нет, код VB6 представляет собой полную, формальную и проверенную на практике спецификацию этой функциональности, а также множество технических фактов о том, как приложение работает за кулисами. Сбор, перекодирование и повторное тестирование всех этих функциональных / технических требований «с нуля» очень дорого и сложно. Чтобы управлять стоимостью и риском проекта, вы должны «заработать» унаследованный код. Вопрос в том, как это сделать, а также обеспечить более низкую стоимость владения после миграции.

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

  1. запустить перевод
  2. сборка / просмотр / тестирование сгенерированного кода для определения / уточнения необходимых улучшений кода
  3. если сгенерированный код «достаточно хорош», перейдите к завершению работы в .NET
  4. перенастроить переводчик для реализации необходимых улучшений (при необходимости)
  5. Перейти к 1

Результат работы инструмента не обязательно должен быть «идеальным» (программное обеспечение никогда не бывает ...), он просто должен быть «достаточно хорошим». То, что «достаточно хорошо» упомянуто в шаге 3, является критическим вопросом. По сути, это означает, что качество кода - с точки зрения его функциональной корректности и соответствия вашим стандартам - таково, что команда разработчиков знает, что потребуется, чтобы завершить миграцию, а затем продолжить работу / обслуживание приложения - И они уверены, что они могут сделать это в течение заданного времени и ресурсов. Для очень большой кодовой базы «достаточно хороший» является «очень хорошим», потому что слишком дорого и рискованно пытаться завершить и впоследствии поддерживать низкокачественную миграцию. Как правило, чем больше код и чем меньше бюджет, тем эффективнее должен быть процесс миграции.

Также некоторые мысли о «завершении работы в .NET»: наличие правильно сформированного кода в .NET является важной вехой. Существуют хорошие инструменты рефакторинга, аналитики и модульного тестирования от сообщества .NET, которые могут помочь вам ускорить ваши усилия по завершению миграции. Вы будете использовать Visual Studio очень рано, чтобы экспериментировать и улучшать редизайн, а также отлаживать / тестировать приложение. Возможность работать со всей вашей кодовой базой в .NET и с Visual Studio на ранних этапах миграции является ключевым преимуществом (и важной частью) подхода с помощью инструментов.

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

Отказ от ответственности: я работаю на великих миграций. На нашем сайте имеется гораздо больше информации, включая примеры использования того, как этот инструмент помог перенести более 1М LOC VB6 на переработанный C #, и руководство пользователя gmStudio, в котором подробно описаны продукт и методология.

6 голосов
/ 20 января 2010

Ознакомьтесь с «1001 *» М. Фезерса «Эффективная работа с устаревшим кодом» - здесь обсуждаются подводные камни улучшения, рефакторинга и миграции, а также непроверенный код.

2 голосов
/ 03 февраля 2010

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

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

Как уже говорилось, в .NET есть несколько очень хороших инструментов для рефакторинга и анализа кода, в дополнение к пакетным тестам. Инструменты автоматического преобразования, такие как Visual Basic Upgrade Companion ArtinSoft, могут быть настроены для обеспечения соблюдения стандартов кодирования или значительного улучшения кода во время преобразования. Это в сочетании с другими инструментами модификации кода, такими как ReSharper , значительно ускорит ваш переход на .NET.

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

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

По сути, любые новые пользовательские элементы управления должны быть написаны на .NET и отображаться как элементы управления ActiveX для использования приложением VB6. Аналогично, новые функции DLL должны быть размещены в сборках .NET, которые можно использовать через COM. Таким образом, когда придет время для миграции, вам не придется беспокоиться об этих элементах управления или библиотеках.

2 голосов
/ 20 января 2010

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

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

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

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

2 голосов
/ 20 января 2010

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

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

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

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

Ключом к переводу его с VB6 на VB.NET (например) является использование библиотеки Interop - вот одна статья: http://support.microsoft.com/kb/817248

Еще одна, гораздо более поздняя мысль: получить MZ-Tools и использовать их инструмент анализа, чтобы найти избыточный код и избавиться от него. Мне удалось устранить что-то вроде пяти-десяти процентов кода в старом унаследованном продукте в моей компании.

1 голос
/ 20 января 2010

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

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

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

...