Від теми журналу до практики проєкту
Відповідні сторінки послуг і технічні сторінки до публікації
У багатьох IT‑відділах ситуація схожа: стабільний, прив’язаний до процесів Delphi-десктопний додаток забезпечує критичні операції, тоді як нові вимоги тиснуть у бік Web, порталів, мобільного використання та інтеграції з хмарними сервісами. Водночас C# у багатьох компаніях встановлено, коли йдеться про сервіси, Web‑API та інтеграцію ідентифікації. Тому ключове питання вже не «Delphi або C#?», а: C# і Delphi в одній спільній архітектурі так поєднати, щоб експлуатація, супровід, зберігання даних та безпека залишалися контрольованими.
Цей допис описує практичні принципи архітектури, що довели свою придатність у корпоративних середовищах, де не все можна або не потрібно будувати наново. Фокус зроблено на чітких відповідальностях між десктоп‑клієнтом, сервісами, даними та інтерфейсами — і на тому, як планувати кроки модернізації з мінімальним ризиком, не підриваючи поточні процеси.
Чому змішані стекі в компаніях є нормою
Розвинені цифрові корпоративні рішення рідко виникають на «чистому аркуші». Delphi-додатки часто розширювалися протягом багатьох років, близько до предметних процесів, з об’ємною логікою даних і глибоким знанням виняткових випадків. Паралельно з’явилися нові вимоги: портали самообслуговування, автоматизований обмін даними, підключення DMS/CRM/ERP, багатоклієнтність, посилена аудиторність або Single Sign‑on.
C# у цьому контексті часто пропонує переваги для веб‑ та сервісних екосистем: широкий спектр хостингу, стандартизована проміжна прошарок, добра інтеграція з Identity Provider та усталені патерни для Web‑API. Delphi залишається сильним, коли йдеться про продуктивні Windows-десктоп‑клієнти, довгостроково підтримувані VCL‑додатки або специфічні мультиплатформені клієнти (наприклад через FMX).
Тому поєднання — це не «особливий випадок», а реалістична відповідь на захист інвестицій і тиск модернізації. Важливо, щоб спільна експлуатація не перетворилася на довготривалу «будівельну площадку».
Принцип архітектури: чіткі шари замість мовних меж
Коли зустрічаються дві технологічні «мови», виникає спокуса організувати розмежування за мовами («Усе Delphi — Legacy, усе C# — нове»). Технічно це часто працює короткостроково, але з часом призводить до тертя: дублювання бізнес‑правил, нечітких зон відповідальності та важко відтворюваних помилок.
Натомість виправдала себе предметна шарифікація, часто реалізована як Layer-3 архітектура: презентація (UI), домен (бізнес‑логіка) та інфраструктура (доступ до даних, зовнішні системи). Суть не стільки в підручниковій моделі, скільки в її конкретному ефекті в повсякденності: рішення щодо даних, валідацій і робочих процесів приймаються в одному місці і надаються через стабільні інтерфейси.
У змішаній архітектурі це практично означає: Delphi може й надалі забезпечувати UI‑частину (або певні робочі процеси), тоді як C# сервіси інкапсулюють предметну доменну шар — або навпаки. Важливо, щоб межа між шарами була технічно чистою і тестованою.
C# та Delphi в одній спільній архітектурі: три перевірені шаблони інтеграції
Для інтеграції Delphi та C# немає «єдиного» правильного шляху. Хороші рішення орієнтуються на експлуатацію, вимоги безпеки, затримку, обсяг даних і цикли випуску. На практиці виділилися три шаблони.
1) Service-Orientierung über HTTP/REST als Standardkopplung
Найбільш стійким для експлуатації та подальшого розвитку часто є поєднання через REST-API (HTTP‑інтерфейси). Delphi‑клієнти викликають сервіси C# або Delphi; портали C# використовують ті самі кінцеві точки. Така розвʼязаність робить релізи більш передбачуваними: оновлення клієнта не обовʼязкове, якщо API зберігає назадсумісність.
Важлива професійна реалізація: таймаути, повторні спроби, ідемпотентність (повторні запити без побічних ефектів), чіткі коди помилок та стратегія версіонування. Для адміністрування та експлуатації також значущі: уніфіковані логи, відстежувані Request‑IDs і добре вимірювані часи відповіді.
2) Gemeinsame Datenbank: nur mit klaren Spielregeln
Спільний доступ до бази даних між Delphi і C# виглядає привабливо через швидкість на початковому етапі. З часом це стає ризиковим, якщо обидві системи прямо записують у ті самі таблиці. Причина: бізнес‑правила зміщуються в тригери, stored procedures або «деінде в клієнті». Це ускладнює аналіз помилок і аудит.
Якщо спільна база даних неминуча (наприклад, у перехідних фазах), допомагають чіткі правила:
- Централізувати операції запису: одна система є «System of Record» для визначених сутностей.
- Визначити договори: представлення (Views) або API як стабільний шар читання замість прямого доступу до таблиць.
- Планувати вікна міграцій: зміни в базі даних завжди розгортати назадсумісно (наприклад, нові стовпці спочатку робити опційними).
Технічно база даних у такому випадку є інфраструктурним компонентом, а не шиною інтеграції.
3) Messaging/Events für asynchrone Prozesse
Для розвʼязаних процесів (наприклад, імпортні прогони, повідомлення, доопрацювання, інтерфейсні завдання) доцільна асинхронна модель: одна система публікує події, інша їх обробляє. Це знижує прямі залежності та стабілізує пікові навантаження.
Для ІТ‑керівництва та адміністраторів важливе наступне: моніторинг (довжини черг), Dead‑Letter‑концепції (невдалі повідомлення), поведінка при повторних запусках і чітка предметна ідемпотентність. Події не замінюють акуратне управління основними даними, але є корисним інструментом для надійних ланцюгів процесів.
Datenverträge und Kompatibilität: der unterschätzte Kern
Незалежно від патерну інтеграції якість контрактів даних визначає стійкість. Контракт даних — це обовʼязковий опис полів, типів, обовʼязковості/опціональності та семантики. В REST‑API це зазвичай JSON; важливо не «JSON як такий», а дисципліна в поводженні зі змінами.
Перевірені правила, що помітно спрощують експлуатацію:
- Розширювати замість ламати: додавати нові поля, а старі спочатку продовжувати віддавати.
- Документувати семантику поля: не лише «string», а, наприклад, ISO‑формат дати, часовий пояс, допустимі стани.
- Толерантне ставлення до значень enum: клієнти повинні витримувати невідомі значення (forward‑compatibility).
- Свідомо застосовувати версіонування API: не кожен реліз потребує нової версії; але Breaking Changes мають бути однозначно ізольовані.
Ці пункти особливо важливі, коли Delphi‑десктоп‑клієнти не можуть оновлюватися так часто, як веб‑сервіси.
Аутентифікація та авторизація: спільна модель безпеки
Змішані архітектури рідко дають збій через «техніку», частіше через непослідовну безпеку. Для підприємства важливо: хто має право на що? Як це перевіряється? Як це аудитується? Спільна модель уникає дублювання управління користувачами та суперечливих ролей.
На практиці це веде до централізованого шару ідентичності: наприклад через SAML 2.0 (федеративний Single Sign-on, часто в корпоративному середовищі) або OpenID Connect (на базі OAuth2, часто для сучасних веб-API). C#-Services лишаються зазвичай безпосередньо приєднуваними до Identity Provider; Delphi-Clients можуть отримувати токени та відправляти їх у викликах API. Важливо, щоб і настільні застосунки не отримували «особливих прав» через прямий доступ до бази даних.
Для адміністраторів централізовано:
- Термін дії токенів та стратегія оновлення (щоб клієнти працювали стабільно й водночас залишалися безпечними)
- Аутентифікація сервісів між собою для внутрішньої комунікації (наприклад mTLS або підписані токени)
- Принцип найменших привілеїв: ролі та права не надавати занадто широко
- Журнали аудиту: прозоро протоколювати дії, що мають значення для безпеки
Операційні концепції: Windows- та Linux-Services, IIS та процеси в щоденній експлуатації
Архітектура в організації хороша лише тоді, коли її можна експлуатувати: оновлення можна планувати, помилки локалізувати, навантаження контролювати. У змішаних ландшафтах найпоширеніші варіанти експлуатації:
- Windows- та Linux-Services: підходять для фонових завдань, прогонів інтерфейсів, worker-процесів; добре інтегруються в класичні моделі експлуатації Windows-серверів.
- Windows- та Linux-Services/Daemon: доцільні для контейнеризованих або VM-орієнтованих моделей експлуатації; часто стабільні в тривалій роботі, хороша автоматизація через systemd.
- Microsoft IIS: усталений хостинг для веб-застосунків та сценаріїв зворотного проксінгу в Windows-центричних середовищах.
Важливо, щоб Delphi- та C#-компоненти дотримувалися схожих стандартів експлуатації: послідовні Health-Endpoints (Lebenszeichen), чітко визначені таймаути, обмежене споживання ресурсів, а також прозора процедура розгортання та відкату. Це зменшує «technologiespezifische» виняткові підходи в експлуатації.
Логування, трасування та метрики: спільний рівень Observability
Особливо при двох стекових технологіях наскрізні ланцюжки діагностики є вирішальними. Типова проблема: Delphi-клієнт повідомляє «помилка при збереженні», C#-сервіс має таймаут, база даних повідомляє про блокування – без спільного контексту.
На практиці виправдані такі підходи:
- Кореляційні ID для кожного запиту (Client → API → DB), щоб журнали можна було зіставити.
- Структуроване логування (ключ/значення замість суто текстових рядків), щоб мати можливість фільтрувати.
- Метрики для латентності, частоти помилок, довжин черг і використання ресурсів.
- Класифікація помилок: бізнес-помилки (валідція) відокремлено від технічних помилок (таймаут, мережа).
Ці основи економлять на практиці більше часу, ніж будь-які дискусії про «правильну мову».
Доступ до даних і міграція: BDE-заміна, FireDAC та сучасні бази даних
У Delphi-середовищах доступ до даних історично відіграє значну роль. Якщо ще використовуються старі шляхи доступу, такі як Borland Database Engine (BDE), виникає додатковий тиск: оновлення операційної системи, переходи на 64‑бітову архітектуру, доступність драйверів, вимоги до безпеки. BDE-заміна у такому випадку — це не лише модернізація, а й зниження ризиків.
Типовим є перехід на BDE-заміна з нативним підключенням (сучасний шар доступу до даних у Delphi), поєднаний з базою даних, яка зручно керується в експлуатації (наприклад PostgreSQL, SQL Server, MariaDB). Для спільної Delphi/C#-архітектури важливі два аспекти:
- Межі транзакцій: хто ініціює/фіксує транзакції, і як регулюються паралельні операції запису?
- Стратегія блокувань та ізоляції: щоб робочі процеси десктоп-клієнтів і сервіси не блокували один одного.
При міграціях виправдовує себе покрокове планування: спочатку модернізувати шар драйверів і доступу, потім консолідувати модель даних, після цього стабілізувати інтеграційні інтерфейси. Так джерела помилок стають ізольованими, а відкати — реалістичними.
Release-Management: unterschiedliche Update-Zyklen unter einen Hut bringen
Постійною точкою напруження є частота оновлень: веб‑сервіси можна розгортати частіше, десктоп‑клієнти часто рідше (вікна розгортання, комунікація з користувачами, пакування). Спільна архітектура має враховувати цю асиметрію.
Практичні наслідки:
- Зворотна сумісність API — обовязкова, а не опціональна.
- Feature Flags (функціональні перемикачі) допомагають включати нові можливості контрольовано на серверній стороні.
- Міграції схеми повинні виконуватися поетапно: спочатку розширити базу даних, потім сервіс починає використовувати нові елементи, після цього оновлюється клієнт.
- Чітка політика виведення з експлуатації: старі кінцеві точки або поля видаляти лише після визначеного періоду.
Особливо в регульованих середовищах важливо зафіксувати ці правила письмово як архітектурні рамки, щоб рішення не винаходилися заново в кожному проєкті.
Типові підводні камені та як їх систематично уникнути
З операційної точки зору найбільш поширені проблеми в змішаних Delphi/C#-ландшафтах добре передбачувані. Якщо їх адресувати рано, довгострокові витрати відчутно зменшаться.
Підводний камінь 1: подвійна бізнес-логіка
Якщо Delphi-клієнт і C#-сервіс реалізують одні й ті самі правила по-різному, виникають «примарні помилки»: процес працює в UI, але зазнає невдачі під час імпорту через API. Протидія: централізувати правила у доменному шарі (сервіс) або чітко розподілити їх за функціональністю, включно з однозначними відповідями валідації.
Підводний камінь 2: обхідні рішення в UI замість акуратних інтерфейсів
«Швидко ще записати поле в базу даних» виглядає в окремому випадку нешкідливо, але створює тіньові інтерфейси без логування, автентифікації та версіонування. Краще: послідовно використовувати визначені кінцеві точки, навіть якщо на початку це вимагає більше дисципліни.
Підводний камінь 3: неясні зони відповідальності в експлуатації
Якщо не зрозуміло, яка команда відповідає за який сервіс, який лог і які параметри експлуатації, пошук помилок перетворюється на пінг-понг. Практично допомагає карта сервісів (який сервіс, які залежності, які порти, які внутрішні SLA) та уніфіковані Runbooks для типових збоїв.
Підводний камінь 4: відсутність консистентності в безпеці
Портал зі SSO, але десктопний клієнт із локальними обліковими записами адміністраторів — у багатьох аудитах це проблема. Спільна модель ідентичності та ролей знижує ризики та навантаження на підтримку.
Допомога у прийнятті рішення: що залишати в Delphi, що переносити в C#?
Розумний розподіл залежить скоріше від близькості до процесів і вимог експлуатації, ніж від ідеології. Як орієнтир з погляду архітектури та експлуатації:
- Delphi часто підходить для: існуючих Windows-десктоп-клієнтів (VCL), дуже реактивних UI-воркфлоїв, сценаріїв близьких до офлайну, довготривалої підтримки еволюціонованих інтерфейсів.
- C# часто підходить для: центральних REST-API, інтеграційних сервісів до ERP/DMS/CRM, компонентів, близьких до Identity, порталів та бекенд-процесів з високою частотою змін.
- Свідоме рішення: логіку даних і валідацію не слід тримати «в клієнті», якщо існує кілька фронтендів (десктоп, портал, імпортні джоби).
Важливо: мета не в тому, щоб «все перенести в C#», а в тому, щоб створити надійну загальну архітектуру, в якій кроки модернізації плануються і бізнес‑процеси працюють стабільно.
Шлях модернізації: поетапно від застосунку до системи
На практиці спільна архітектура часто є перехідним станом, але довготривалим. Реалістичний шлях модернізації уникає великих ризикових проєктів і орієнтується на вимірювані проміжні цілі:
- Стабілізувати інтерфейси: ввести REST-API як предметну межу, навіть якщо внутрішньо ще не все «ідеально».
- Модернізувати доступ до даних: BDE-Ablösung, драйвери, 64‑Bit-функціональність, чіткі транзакції.
- Централізувати Identity: SSO і модель ролей для всіх шляхів доступу.
- Уніфікувати експлуатацію: Logging/Monitoring/Health, чіткі розгортання, відтворювані середовища.
- Розв’язати предметні модулі: особливо частозмінні частини перемістити в сервіси, UI поступово спростити.
Цей порядок не догматичний, але зазвичай мінімізує залежності: без стабільних інтерфейсів і концепції експлуатації кожна наступна зміна стає дорожчою.
Висновок: інтеграція — це завдання архітектури, а не питання мов
Життєздатне поєднання Delphi і C# не виникає через «мостові бібліотеки», а через чіткі предметні межі, акуратні договори даних і концепцію експлуатації, яка серйозно ставиться до Monitoring, Security і Release-Management. Коли C# і Delphi в спільній архітектурі свідомо грають узгоджені ролі за відповідальністю, компанії отримують передусім одне: модернізацію без розриву процесів. Delphi може й надалі надійно підтримувати стабільні десктоп-воркфлови, тоді як C#-сервіси надають інтеграцію, веб-API та портали як центральні функції платформи.
Якщо ви плануєте поетапно модернізувати існуючу Delphi-ландшафт або чисто підключити сервіси C#, архітектурний рев’ю з фокусом на інтерфейси, дані, експлуатацію та безпеку — найшвидший шлях до обґрунтованих рішень. Детальніше в прямому діалозі:
У фаховому середовищі важливу роль відіграють також Delphi модернізація та REST-API для існуючого програмного забезпечення, коли інтеграції, потоки даних і подальший розвиток повинні коректно взаємодіяти.
Наступний крок
Якщо тема перетворюється на реальний проєкт, архітектуру, наявну інфраструктуру та експлуатацію слід розглядати разом на ранньому етапі.
Ми підтримуємо не лише в окремих питаннях, а й тоді, коли з уривків вихідного коду, питань, пов’язаних із legacy, або ідей порталу має вирости надійний корпоративний проєкт.
- Поточний стан, цільова архітектура та технічні ризики оцінюються спільно.
- REST, доступ до даних, портали та розгортання не відкладаються на пізніші етапи.
- Ви завчасно визначаєте, який підхід є економічно та операційно життєздатним.