Данная статья — с одной стороны — изначально задуманное продолжение моей первой статьи "«Миграция приложений — мифы и реальность», а с другой стороны — ответ на часть комментариев, которые задавали в статье Хабравчане vladsharikov, lair и berez.
Для начала, приведу пример конвертации кода на Delphi в код на C#:
После трансляции, код превращается в такой:
И да, код на C# работает после подключения миграционной библиотеки и компиляции.
Есть более сложные и интересные места — например, реализация свойств с индексами (если кто знает Delphi — поймут), к которым есть доступ по имени, то есть в форме Obj.Items[index], но прямо сейчас под рукой этого кода нет.
Накидал, по-быстрому, небольшое приложение на FoxPro, получилось вот такое:
Внешний вид в C# + WPF ниже.
Извините — полные варианты тем, с заменяемыми кнопками на заголовке окна и сменными же стилями заголовков, искать не стал
Если есть ещё вопросы по примерам конвертации — прошу в комментарии.
P.S. Перевод с Delphi на C# — один из проектов-тестов, которые использовались в процессе отладки конвертера.
P.P.S. Форма на FoxPro сделана «наспех», специально для демонстрации.
Конвертация кода с Delphi на C#
Для начала, приведу пример конвертации кода на Delphi в код на C#:
Код на Delphi
unit Unit3;
interface
type
TMyClass = class
_str: string;
constructor Create;
procedure setStr(s2: string);
public
class var
FClassField: integer;
end;
TMyClassD = class of TMyClass;
procedure DoSomeThing;
implementation
procedure DoSomeThing;
begin
end;
{ TMyClass }
constructor TMyClass.Create;
var
c: char;
i: byte;
cod: integer;
s: string;
cls: TMyClassD;
begin
cls := TMyClass;
inherited;
DoSomeThing;
Val('5', i, cod);
c := '1';
s := c;
end;
var
cls: TMyClass;
s: string;
procedure TMyClass.setStr(s2: string);
begin
s2[4] := 'a';
end;
initialization
cls := TMyClass.Create;
s := '123456';
cls._str := s;
s[3] := '0';
cls.setStr(s);
end.
После трансляции, код превращается в такой:
Код C#
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.IO;
using System.Text;
using FastCode.Delphi.Core._System;
namespace Project3 {
public static partial class Unit3_Module {
public static void Unit3_Initialization_() {
cls = TMyClass.Create();
s = "123456";
cls._str = s;
//s[3] = '0';
s = s.Substring(0, 2) + '0' + s.Substring(3);
cls.setStr(s);
}
public static void DoSomeThing() {
}
internal static TMyClass cls;
internal static string s;
}
public partial class TMyClass : TObject {
public override void __Create__() {
Char c;
byte i;
int cod;
string s;
Class_of_TMyClass cls;
cls = Class_of_TMyClass.Instance;
base.__Create__();
Unit3_Module.DoSomeThing();
System_Module.Val('5'.ToString(), out i, out cod);
c = '1';
s = c.ToString();
}
public void setStr(string s2) {
//s2[4] = 'a';
s2 = s2.Substring(0, 3) + 'a' + s2.Substring(4);
}
public static TMyClass Create() {
TMyClass _instance = new TMyClass();
_instance.__Create__();
return _instance;
}
public string _str;
public static int FClassField;
}
public partial class Class_of_TMyClass {
protected Class_of_TMyClass() {
}
public TMyClass Create() {
return TMyClass.Create();
}
public static Class_of_TMyClass Instance = new Class_of_TMyClass();
public int FClassField { get { return TMyClass.FClassField; } set { TMyClass.FClassField = value; } }
}
}
И да, код на C# работает после подключения миграционной библиотеки и компиляции.
Есть более сложные и интересные места — например, реализация свойств с индексами (если кто знает Delphi — поймут), к которым есть доступ по имени, то есть в форме Obj.Items[index], но прямо сейчас под рукой этого кода нет.
Внешний вид в FoxPro
Накидал, по-быстрому, небольшое приложение на FoxPro, получилось вот такое:
Внешний вид в C# + WPF ниже.
Извините — полные варианты тем, с заменяемыми кнопками на заголовке окна и сменными же стилями заголовков, искать не стал
Здесь три дополнительных темы
Glass
Steel Blue gradient
Metro Light
Glass
Steel Blue gradient
Metro Light
Если есть ещё вопросы по примерам конвертации — прошу в комментарии.
P.S. Перевод с Delphi на C# — один из проектов-тестов, которые использовались в процессе отладки конвертера.
P.P.S. Форма на FoxPro сделана «наспех», специально для демонстрации.
lair
Ох. Вы искренне считаете этот код на C# поддерживаемым?
HackerDelphi Автор
Спасибо за комментарий!
В любом случае, сейчас ведётся работа по «перестройке» кода так, чтобы он выглядел лучше. Многие «сервисные» вещи будут спрятаны за #region...#endregion
lair
Да все вместе. Это код, с которым я бы никогда не хотел иметь дела.
Что, собственно, возвращает нас к началу разговора и вопросу: а зачем вообще «переписывать» код с одного языка на другой? Вот я заказчик, у меня есть работающее приложение на, скажем Java + DB2 — зачем мне его переписывать?
HackerDelphi Автор
основных причин для миграции, как правило, 3:
Конкретно в вашем случае — не вижу глобальных причин для миграции. Java разработчики вроде как на рынке есть, DB2, конечно не так популярен, как Oracle или MS SQL, но тоже вполне себе можно изучить или найти готового разработчика.
Единственной для вас причиной может оказаться желание, к примеру, перенести весь код на платформу .Net, чтобы дальше перенести основную часть, опять-таки к примеру, на ASP.Net и подключить туда клиент Windows Phone / Windows Store / Windows Desktop. Но подозреваю, что конкретно в вашем случае будет решение использовать либо Linux либо Android в качестве клиентского места. В принципе, можно и OSX и Windows — тут простор велик.
Надеюсь — ответил на Ваш вопрос?
P.S. я Попробую чуть позже найти код без такой экзотики, такой как конструкции «class of» и прочее.
lair
Нет, не ответили. Какая разница, есть ли квалифицированные разработчики/устарела ли платформа, если система работает?
HackerDelphi Автор
Бизнес системы почти всегда требуют доработки. Системы, которые начаты в 1985 году (к примеру) требуют доработки всегда.
Менеджмент постоянно хочет новые формочки.
Доработки нужны постоянно.
lair
То есть на самом деле, заказчик хочет развивать систему, но не может этого делать, потому что стоимость внесения изменений в существующую реализацию слишком велика, так?
HackerDelphi Автор
Либо слишком велика, либо вообще невозможна.
lair
(Невозможного не бывает, бывает слишком дорогое)
Это все означает, что то, что получается после переписывания, должно быть дешевле в поддержке и развитии, чем то, из чего оно выросло, а не просто «работать так же, как». Что, в свою очередь, означает требования по качеству и структуре кода.
Я это все к тому, что (по моему опыту), следующий шаг за автоматической конвертаций — ручной рефакторинг со всеми необходимыми этапами, и стоимость этого рефакторинга тоже надо считать в стоимости «переписывания». Иначе результаты несравнимы.
HackerDelphi Автор
Не совсем верно.
В данном случае не применялось никаких инструментов автоматического рефакторинга, который в нашем конвертере очень даже присутствует (в окончательной версии).
Текущая версия — рабочая, но как раз инструменты рефакторинга «по анализу» не встроены — только что перешли на совсем новую модель внутреннего представления данных.
Эти примеры — примеры того, что можно получить «автоматом и дёшево» — многие согласны на такую услугу — лишь бы меньше платить.
А насчёт ручного рефакторинга.
По опыту пары прошлых проектов, конвертированный код использовали «как есть», а вот в процессе развития/отладки (оригинальный код содержал ошибки — как же без них) переписывались достаточно большие участки кода.
Более того, обычно мы предлагаем, кроме чисто конвертации и запуска приложения, услугу по чистке кода и рефакторингу (вовсе не вручную и намного дешевле, чем вручную).
Кроме того, можем, зачастую, предложить и услуги по оптимизации.
lair
Я, очевидно, сужу по коду, который вы показываете, никакого другого для сравнения у меня нет. И этот конкретный код, на мой вкус, к поддержке и развитию непригоден. Соответственно, озвученную выше задачу — получить код более дешевый в поддержке, чем оригинальный — он не решает. Если для того, чтобы код был дешевле в поддержке, нужно применить дополнительные усилия — не важно, ручные или автоматические — их стоимость тоже нужно учитывать в сравнении «автомат vs ручное переписывание».
HackerDelphi Автор
Заметим, я пока что вообще не приводил цен на «автомат».
Более того, даже с учётом доведения кода до «хорошего» с точки зрения целевой платформы (например — уборка «красивых» статик методов «Create» и замена их на нормальные конструкторы, выкидывание Class_of конструкций и подобного) цена наших услуг в разы ниже, чем «ручной перевод».
P.S. Кстати, гарантии, что ручной перевод будет лучше, чем показанный код нет — чаще всего найти действительно толковых программистов и заинтересовать их на 2-3 года подобным проектом крайне тяжело.
lair
Вы утверждали, что это выгоднее по ресурсам, чем ручное переписывание. Нет, я ошибся?
Это зависит от критериев «хорошести», согласитесь?
Зависит от целей проекта и предлагаемых условий. Нам подобное вполне удалось.
HackerDelphi Автор
Там же написано — «С точки зрения целевой платформы» — для большинства платформ есть более-менее вменяемые описания «хорошего» кода.
По-хорошему завидую — искали, очень тщательно, людей, которые способны руками переводить код с FoxPro — нереально, даже если брать не слишком высокий уровень. Перевести код с того же Delphi на C# уже проще, но при условии использования Win Forms, а вот перенос Delphi => WPF уже всё намного грустнее — слишком большая разница в «нутре» библиотек — многие неспособны одновременно и то и то хорошо понимать.
lair
Нет. Есть гайдлайны, но соответствие им не гарантирует хорошего кода.
Надо было искать хороших специалистов в целевой платформе. Специалиста (глубокого) по исходной достаточно одного на пять, если не на десять.
BlessMaster
Попробую ответить за вашего визави. Реальный случай из жизни, причём, совсем не «за новые формочки», а хоть бы как-то заставить работать.
Купили на СТО железку для общения с тем, что в автомобилях 90-х называется «компьютером». К нему прилагается софт, по внешнему виду писанный ещё во времена, когда в моде были контролы Win3.x-style. Всё это добро ещё работает на WinXP, но уже в момент, когда его купили WinXP не продавался, а все ноуты шли с Вистой.
Конечно, было два пути решения — искать б/у ноут или пиратить винду, но это ведь тоже решения тянущие в дремучее прошлое — ноуты ломаются, нелицензионка на предприятии — к добру не ведёт.
При этом производитель железа на тот момент явно испытывал сильную зубную боль от самой идеи переписывания ПО (ассортимент железок большой, рынок — не так уж и велик, кризис, опять же).
Так что, ниша, из-за устаревания систем и прекращения поддержки, наверно, всё-таки есть.
lair
А кто в вашем примере будет пользоваться услугами по автоматической миграции? Те, кто купил софт? А откуда у них исходники, и как они потом будут проверять правильность конверсии? Или производитель? Так у него, вроде бы, зубная боль и так.
(с точки зрения лицензирования такие вещи, афаик, делаются через XP Mode в той же семерке, но это оффтопик)