Как перенести некрасивый и недокументированный код VB6 в.NET

Я знаю, что уже есть вопросы по миграции на 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), …
  • Копирование и вставка повсюду, например, был скопирован проект EXE (без графического интерфейса) с 5000 строками кода, и единственное изменение в копии заключалось в отправке файлов по почте вместо FTP (есть еще 2 копии этого же проекта).).
  • Когда-то у меня была небольшая форма (15 полей), где я должен был решить небольшую проблему (обычно максимум полчаса), каждый раз, когда я что-то менял, это либо не работало, либо приводило к новым ошибкам в форме. Через 2 дня я решил полностью переписать форму, и из ~20 операторов SQL в старой форме в новой сохранилось только 2.
  • даже не спрашивайте о комментариях в коде...

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

Мои настройки

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

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

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

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

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

10 ответов

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

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

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

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

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

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

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

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

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

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

Опытный аналогичный перенос 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/

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

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

Если это довольно большая кодовая база, и она звучит так (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, в котором подробно описаны продукт и методология.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ОБНОВЛЕНИЕ: Стоит отметить, что автоматическая миграция переместит ваши проблемы только на другой язык.

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

Оценка и планирование. Начните с оценки объема проекта и понимания бизнес-логики приложения VB6. Определите зависимости, сторонние компоненты и внешние библиотеки, используемые в коде VB6.

Документация: начните максимально документировать существующий код. Это может включать извлечение бизнес-правил, алгоритмов и структур данных. Используйте такие инструменты, как Doxygen или GhostDoc, для создания документации по коду. Выберите стек технологий .NET:

Решите, хотите ли вы перейти на VB.NET или C#. C# более популярен и имеет лучшую поддержку в экосистеме .NET. Выберите версию .NET, на которую вы хотите перейти (например, .NET Framework или .NET Core/5/6).

Рефакторинг кода: разбейте код VB6 на более мелкие, управляемые компоненты. Замените устаревшие конструкции и методы современными эквивалентами .NET. Например, замените COM-компоненты сборками .NET. Устраните соглашения об именах, стиль кода и проблемы согласованности. Используйте инструменты миграции:

Используйте инструменты миграции, такие как Visual Basic Upgrade Companion (VBUC) из Mobilize.NET или мастер обновления Visual Basic в Visual Studio, чтобы автоматизировать часть миграции. Будьте готовы просмотреть и реорганизовать сгенерированный код вручную.

Модульное тестирование: реализуйте модульные тесты, чтобы гарантировать сохранение функциональности в процессе миграции. В этом могут помочь такие инструменты, как NUnit или MSTest. Перенос данных:

Переносите данные из хранилищ данных VB6 (например, баз данных Access) в современные базы данных, такие как SQL Server.

Модернизация пользовательского интерфейса (UI). Рассмотрите возможность обновления пользовательского интерфейса с использованием современных технологий .NET, таких как Windows Presentation Foundation (WPF) или ASP.NET для веб-приложений. Убедитесь, что пользовательский опыт остается последовательным или улучшенным. Тестирование и обеспечение качества:

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

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

Постоянное обслуживание. Будьте готовы к постоянному обслуживанию и поддержке по мере необходимости.

Источник = https://vocal.media/geeks/migrating-from-v-b6-to-net-core-understanding-why-and-how .

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