Net-Base Rivista

14.07.2026

Rifattorizzare il codice legacy in Delphi: ridurre i rischi, aumentare la manutenibilità, garantire l'operatività

Applicazioni Delphi consolidate nel tempo sono spesso critiche per l’operatività aziendale – ma ogni piccola modifica diventa più costosa. Questo articolo mostra come rifattorizzare codice legacy in Delphi senza mettere a rischio il funzionamento: con una chiara analisi dell’esistente, misure prioritarie, test, dati e...

14.07.2026

Dal tema della rivista alla pratica di progetto

Pagine di servizi e tecniche correlate all'articolo

Video-Botschaft

Rifattorizzare il codice legacy in Delphi: ridurre i rischi, aumentare la manutenibilità, garantire l'operatività

Kurze Einordnung, warum kontrolliertes Refactoring bei geschäftskritischen Delphi-Systemen Betriebssicherheit und Änderungsfähigkeit verbessert, ohne einen riskanten Rewrite zu starten.

Video mit KI erstellt

Transkript anzeigen

Hallo. Kurz ein Thema, das im Betrieb schnell teuer wird.

Der Beitrag heißt: „Legacy-Code in Delphi refactoren: Risiken senken, Wartbarkeit erhöhen, Betrieb sichern“. Wenn jede kleine Änderung ein potenzieller Ausfall ist, werden Releases langsam, und niemand fasst das System gern an.

Legacy heißt hier nicht nur „alt“. Es heißt: schwer erklärbar, stark verknüpft, und dadurch riskant.

Refactoren bedeutet: umbauen, ohne das Verhalten zu ändern. Also kein Rewrite, sondern ein kontrollierter Umbau am fahrenden System.

Wichtig für Admins und IT-Leitung ist die Reihenfolge: erst Bestandsaufnahme. Was ist geschäftskritisch?

Wo hängen Datenbank, Schnittstellen und Jobs dran? Dann kleine, priorisierte Schritte, abgesichert durch Tests und sauberes Logging, damit Fehler auffallen, bevor Nutzer sie melden.

Wenn Sie dazu Fragen haben, schauen wir es gern gemeinsam an.

Chi gestisce un’applicazione Delphi critica per il business conosce la tensione: funziona in modo stabile, mappa i processi core ed è profondamente integrata con database, interfacce e flussi di lavoro. Contemporaneamente il costo delle modifiche e il rischio aumentano a ogni release, perché nel corso degli anni si sono accumulati compromessi, casi particolari e dipendenze. Proprio qui interviene la rifattorizzazione del codice legacy in Delphi: non come progetto di ‚riscrittura‘, ma come ristrutturazione controllata sul sistema in esercizio – con effetti misurabili su manutenibilità, sicurezza del rilascio e esercizio.

Nella pratica il refactoring raramente fallisce a causa di Delphi in sé, ma per mancanza di trasparenza: cosa è critico dal punto di vista funzionale? Dove si trovano i debiti tecnici (ossia difetti strutturali che rendono più costose modifiche future)? Quali parti possono essere toccate nelle finestre di manutenzione e quali no? E come si evita che il «riordino» introduca nuovi errori o problemi di performance in produzione? Questo contributo descrive un approccio operativo che coinvolge la direzione IT e l’amministrazione: dalla rilevazione dello stato alla tematiche di architettura e dati fino a test, processo di rilascio e questioni di sicurezza.

Cosa significa davvero „Legacy“ nei progetti Delphi?

„Legacy“ viene spesso equiparato a „vecchio“. Nel contesto aziendale il codice legacy è però primariamente codice il cui rischio di modifica è elevato e il cui comportamento è spiegabile solo parzialmente. Può trattarsi di un’applicazione VCL (Visual Component Library, classica UI desktop Windows), ma anche di un servizio, uno scheduler o un sistema client-server.

Caratteristiche tipiche del codice legacy in ambienti Delphi sono:

  • Forte accoppiamento: UI, accesso ai dati e logica di business sono mescolati; le modifiche generano effetti collaterali.
  • Regole implicite: la logica di dominio risiede in eventi, variabili globali o trigger del database, non in moduli chiari.
  • Accessi ai dati obsoleti: ad es. BDE (Borland Database Engine) o componenti proprietarie; assenza di strategie di pooling/timeout.
  • Gestione errori incoerente: le eccezioni vengono ignorate, i messaggi non finiscono nel logging centrale.
  • Fragilità di build e release: dipendenze, problemi di percorsi, impostazioni del compilatore differenti, interventi manuali.
  • Mancanza di test: la conoscenza è nella testa delle persone o nella «sequenza di click» degli utenti esperti.

Importante: il codice legacy non è automaticamente «cattivo». Spesso è il risultato di pressione sui tempi, cicli tecnologici e decisioni pragmatiche. Il refactoring è allora un investimento nella controllabilità – dal punto di vista dell’esercizio, della sicurezza, della compliance e della velocità di cambiamento.

Refactoring vs. Rewrite: cosa cambia per l’esercizio e il rischio

Una riscrittura (sviluppo da zero) promette un punto di partenza pulito, ma spesso comporta lunghe fasi in parallelo, nuove classi di errori e alti rischi di migrazione. Il refactoring invece mira a un miglioramento incrementale mantenendo la capacità di rilascio continuo. Per l’operatività IT e le unità di business questa è spesso la differenza decisiva: il sistema resta produttivo e i miglioramenti vengono rilasciati in pacchetti gestibili.

Distinzione pratica:

  • Refactoring: si migliora la struttura, il comportamento esterno dovrebbe restare invariato. Focus: manutenibilità, testabilità, stabilità, margini di performance.
  • Restrutturazione/modernizzazione: oltre a ciò, modifiche comportamentali mirate, p.es. nuove interfacce, nuovo database, nuovi target di piattaforma.
  • Rewrite: nuova base di codice, in genere nuova UI/architettura; richiede migrazione dei dati, dei processi e delle interfacce – spesso «Big Bang» o una lunga fase di transizione.
  • Per i decisori il punto è centrale: il refactoring non è un fine a sé stesso, ma una leva per ridurre i rischi di cambiamento. Questo è immediatamente rilevante per l’esercizio quando l’applicazione influenza processi 24/7, flussi vicini alla produzione o portali orientati al cliente.

    Rifattorizzare il codice legacy in Delphi: iniziare con una valutazione attendibile dello stato di fatto

    Il primo passo non è uno strumento, ma una visione condivisa dei rischi e degli obiettivi. Senza questa visione il refactoring finisce presto in un «rifacciamo un po’ di ordine qui» – e proprio questo è difficile da giustificare in esercizio.

    1) Rilevare criticità e realtà operativa

    Accertate quali parti sono veramente critiche per il business: chiusura di fine giornata, interfacce verso ERP/DMS/CRM, raccolta dati di produzione, fatturazione, gestione dei diritti. Aggiungete parametri operativi: finestre di manutenzione, possibilità di rollback, monitoring, volume dei dati, requisiti di latenza.

    Domande guida utili:

    • Quali funzioni devono continuare a funzionare anche in caso di guasti parziali (capacità di degradazione)?
    • Dove si trovano i punti singoli di guasto (z. B. uno scheduler centrale)?
    • Quali dati sono sensibili dal punto di vista normativo o della protezione dei dati?
    • Quali integrazioni sono le più soggette a malfunzionamenti (importazione di file, TCP/IP, SOAP/REST, messaging)?

    2) Rendere visibili i debiti tecnici – non solo lo stile del codice

    Nei progetti Delphi i debiti tecnici sono spesso di natura architettonica: stati globali, dipendenze cicliche tra unità, accessi ai dati difficili da testare, o eventi UI usati come «orchestrazione». Le metriche (p.es. complessità, dimensione delle unità, grafo delle dipendenze) sono utili, ma valgono solo se tradotte in interventi concreti.

    Uno schema pratico è una matrice 2×2:

    • Modificato frequentemente & rischioso: massima priorità per il refactoring.
    • Modificato frequentemente & poco rischioso: migliorare processi/test, interventi strutturali minori.
    • Modificato raramente & rischioso: stabilizzazione/mitigazione (test, logging), non necessariamente «abbellirlo».
    • Modificato raramente & poco rischioso: lasciarlo intenzionalmente com’è.

    3) Inventariare le dipendenze: dati, interfacce, ambiente di esecuzione

    Per l’amministrazione e i responsabili di progetto è cruciale sapere cosa dipende dall’esterno del codice: backend di database, ODBC/OLE DB, condivisioni file, flussi di stampa e PDF, COM/ActiveX, automazione Office, Windows-services, task pianificati, certificati, configurazioni proxy.

    Qui i costi di refactoring emergono spesso in modo indiretto: una modifica «piccola» può impattare la logica degli installer, i diritti d’accesso o le regole del firewall. Queste conseguenze collaterali dovrebbero essere documentate precocemente in una mappa tecnica.

    Zone problematiche tipiche nel legacy Delphi e come affrontarle in modo mirato

    Il refactoring diventa gestibile quando mira a pattern ricorrenti. I seguenti ambiti sono in pratica spesso i maggiori fattori di rischio e di costo.

    Forms monolitiche: quando l’interfaccia utente tiene insieme il sistema

    Molte applicazioni VCL sono cresciute storicamente in modo „Form-driven“: il form carica i dati, verifica le regole, scrive i risultati, avvia report e aggiorna altre maschere. Questo funziona finché non intervengono più team o anni di storia delle modifiche.

    Un percorso operativo collaudato è alleggerire gradualmente la UI:

    • Introdurre servizi vicini ai casi d’uso: operazioni di dominio come metodi chiaramente nominati invece di catene di eventi.
    • Incapsulare l’accesso ai dati: query/transazioni non negli eventi della UI, ma in layer di Data Access.
    • Usare DTOs/modelli (semplici oggetti dati) per separare lo stato del form dallo stato del database.

    Lo scopo non è la «purezza dei pattern», ma migliore testabilità e meno side effect: una modifica alla validazione o al calcolo non dovrebbe mettere a rischio l’intero flusso di click nella UI.

    Datenzugriff modernisieren: BDE ablösen, FireDAC konsistent einsetzen

    Se sono ancora in uso BDE o componenti dati disomogenee, il refactoring è spesso anche una modernizzazione del rischio operativo. BDE non è solo obsoleta, ma spesso difficile da gestire: driver, configurazione, dipendenze a 32 bit e mancanza di meccanismi di sicurezza moderni.

    BDE-sostituzione con integrazione nativa (la moderna libreria di accesso ai dati di Delphi) è in molti scenari uno standard sensato, se applicata con coerenza: parametri di connessione unificati, confini di transazione chiari, timeout, pooling e gestione pulita delle eccezioni. Interventi di refactoring tipici in questo ambito:

    • Uniformare la gestione delle connessioni: factory/provider centrali invece di «ogni form ha la sua Connection».
    • Rendere esplicite le transazioni: Begin/Commit/Rollback come parte del caso d’uso, non nascosti nella UI.
    • Usare query parametrizzate in modo coerente per ridurre i rischi di SQL injection e i problemi con caratteri speciali.
    • Definire timeout e meccanismi di retry, in modo che problemi di rete non provochino maschere „congelate“.

    Per l’operazione IT è importante che le nuove strategie di connection siano concordate con il team di gestione del database (p. es. connessioni massime, dimensione del pool, gestione dei deadlock, finestre di manutenzione per modifiche di schema).

    Unit-Abhängigkeiten und „globale Zustände“ als Hauptursache für Seiteneffekte

    Unit di Delphi con ampie sezioni interface, molti entry in Uses e singleton globali sono tipici acceleratori di side effect. Una piccola modifica in una unit può innescare ricompilazioni a cascata o rompere sequenze di inizializzazione nascoste.

    Passi pragmatici che si sono dimostrati efficaci nei progetti legacy:

    • Stabilire direzioni di dipendenza: p. es. UI → Application Services → Domain/Logica → Data Access → Infrastruttura.
    • Centralizzare l’inizializzazione: sequenza di avvio chiara invece di Unit-Initialization come controllo nascosto.
    • Ridurre le variabili globali: mantenere lo stato in oggetti, chiarire durata e responsabilità.

    Questo migliora la stabilità: se l’avvio è deterministico, i guasti dopo aggiornamenti o modifiche di configurazione sono più gestibili.

    Threading und Synchronisation: Stabilität vor „Performance-Optimierung“

    Molte applicazioni legacy diventano nel tempo concorrenti: import in background, polling, comunicazione con dispositivi, elaborazioni parallele. Senza regole chiare si generano deadlock, blocchi dell’interfaccia o race condition (conflitti di accesso dovuti a esecuzione simultanea).

    Per il funzionamento e il supporto operativo questo è un problema, perché genera spesso errori «non riproducibili». Il refactoring dovrebbe mirare qui a standard:

    • Ownership chiara per Thread/Task e shutdown definito (così aggiornamenti/arresto non restano bloccati).
    • Logging per worker con ID di correlazione, per ricostruire i flussi.
    • Minimizzare la sincronizzazione e incapsulare strettamente gli accessi all’interfaccia utente (regola del thread UI).

    Se desiderate approfondire, è sensato inserire un link interno a un articolo sui pattern robusti con TThread e Synchronize, perché l’argomento è spesso il collo di bottiglia per la stabilità nel refactoring di legacy.

    Obiettivo architetturale: Layering come strumento, non come dogma

    Un quadro obiettivo praticabile per molte Delphi-soluzioni esistenti è una chiara struttura a layer (spesso intesa come „3 livelli“): Presentazione (UI), logica applicativa (Use Cases/Services) e accesso ai dati (Repositories/DAO). Importante è la prospettiva operativa: il layering facilita i test, gli aggiornamenti e il successivo disaccoppiamento delle interfacce.

    Vantaggi concreti per le aziende:

    • Aggiungere interfacce (es. REST-API), senza dover duplicare la logica UI.
    • Modernizzazione parziale: un cambio di database o la migrazione a BDE-Ablosung mit nativer Anbindung può essere concentrata in un unico layer.
    • Manutenzione: gli errori si isolano più rapidamente perché le responsabilità nel codice sono più chiare.

    Un obiettivo realistico considera che i sistemi legacy raramente diventano „puri“. Decisivo è che la direzione sia corretta e che le nuove modifiche non indeboliscano nuovamente la struttura.

    Strategia di test per Delphi-Refactoring: come congelare il comportamento prima di ristrutturare

    Il refactoring senza test è un rischio nei sistemi critici per il business. Allo stesso tempo l’automazione completa dei test spesso non è realizzabile a breve termine. Il principio centrale è quindi: testare in modo mirato dove il rischio e la pressione del cambiamento sono elevati.

    Golden Master e regressione: pratico per i sistemi legacy

    Un „Golden Master“ è una referenza del comportamento corrente: input e output attesi vengono registrati per rilevare deviazioni dopo le modifiche. È adatto a report, calcoli, esportazioni, pipeline di importazione o risposte di interfacce.

    Importante per il funzionamento: i test Golden Master riducono il rischio che effetti collaterali emergano solo dopo il rollout — e supportano decisioni rapide sui hotfix, perché la deviazione è misurabile concretamente.

    Test di integrazione relativi a database e interfacce

    Molti errori non nascono nella logica di dominio pura, ma ai confini di sistema: transazioni, encoding (es. Unicode), timestamp, separatori decimali, permessi, disturbi di rete. I test di integrazione dovrebbero quindi coprire almeno i seguenti aspetti:

    • Comportamento delle transazioni in caso di errori (rollback, aggiornamenti parziali, blocchi).
    • Encoding in import/export (CSV, XML, JSON), in particolare per caratteri speciali.
    • Profili di performance per volumi di dati tipici, per rilevare degradi progressivi delle prestazioni.

    I casi di test manuali rimangono – ma strutturati

    Dove manca (ancora) l’automazione, piani di test manuali strutturati, legati alle release, sono utili. Dal punto di vista dell’amministrazione è rilevante che i casi di test includano anche aspetti operativi: percorso di installazione/aggiornamento, permessi, configurazione, logging/monitoring, stampanti/PDF, percorsi di rete.

    Dati e migrazione: il refactoring viene spesso deciso in base allo schema

    Nei sistemi Delphi le strutture di database si sono sviluppate nel corso degli anni. Il refactoring spesso si scontra con tabelle „storiche“, campi duplicati o colonne sovraccariche dal punto di vista funzionale. Il punto critico: le modifiche allo schema impattano il funzionamento, Backup/Restore, la replica, il reporting e le interfacce.

    Rendere pianificabili le modifiche allo schema

    Consolidato è l’approccio basato su migrazioni di database chiaramente versionate: ogni modifica allo schema viene documentata come passo riproducibile, inclusa la strategia di rollback. Anche se le migrazioni vengono eseguite inizialmente manualmente, la disciplina è decisiva: niente „modifichiamo rapidamente in produzione“.

    Per la sicurezza dei release dovreste definire:

    • Necessità di downtime: migrazione online possibile o è necessario un finestra di manutenzione?
    • Strategia di rollback: compatibilità dei dati in caso di rollback, backup prima della migrazione, piano di riavvio.
    • Fase di compatibilità: l’applicazione può operare per un periodo transitorio con schema vecchio e nuovo (es. colonne aggiuntive, Views).

    Non sottovalutare qualità dei dati e pulizia

    Un refactoring spesso mette in luce problemi di dati che prima „galleggiavano“: valori non validi, incoerenze, chiavi esterne mancanti. È fondamentale decidere a livello di dominio cosa considerare corretto. Sul piano tecnico l’applicazione dovrebbe d’ora in poi validare in modo più rigoroso e registrare gli errori in modo tracciabile, invece di correggerli silenziosamente.

    Integrare interfacce senza destabilizzare il sistema legacy

    Molte aziende refactoring dei patrimoni Delphi perché nuove esigenze impongono integrazioni: portali, BI, processi mobile, collegamenti con partner. L’errore più frequente è alimentare le interfacce direttamente dalla logica UI o „da qualche parte nel codice“. È preferibile basare le interfacce su uno strato di servizi consolidato, che viene introdotto già durante il refactoring.

    Quando si aggiunge un’API REST (Representational State Transfer, tipica Web-API su HTTP/JSON), dal punto di vista operativo e della sicurezza sono particolarmente importanti:

    • AuthN/AuthZ: separare chiaramente autenticazione e autorizzazione; es. token, SAML 2.0 nel contesto di SSO aziendale, modelli di ruolo chiari.
    • Rate Limits und Timeouts: per evitare che chiamanti esterni blocchino il backend.
    • Versionamento: definire versioni API per non rompere i client ad ogni modifica.
    • Osservabilità: log strutturati, ID di correlazione, metriche (tassi di errore, latenze).

    Un link interno a un approfondimento sull’implementazione di un’API REST per software esistente può collegarsi molto bene a questo contenuto, perché le interfacce nei progetti di modernizzazione raramente sono un „add-on“, ma costituiscono un prodotto operativo a sé stante.

    Sicurezza e compliance: il refactoring come opportunità per chiudere le vulnerabilità

    Legacy spesso significa che le ipotesi di sicurezza sono più vecchie dello scenario delle minacce odierno. Durante il refactoring dovreste almeno verificare se il sistema richiede aggiornamenti nei seguenti ambiti:

    • Credenziali und Secrets: nessuna password in file INI o nel codice; conservazione sicura e rotazione.
    • Crittografia del trasporto: TLS per le interfacce, gestione corretta dei certificati.
    • Least Privilege: utenti del database e permessi sui file il più ridotti possibile; ruoli separati per lettura/scrittura/amministrazione.
  • Auditabilità: modifiche tracciabili ai dati critici (Chi? Cosa? Quando?), senza trasformare i dati di log in problemi di protezione dei dati.
  • Per la direzione IT si tratta di un vantaggio aziendale fondamentale: il refactoring non solo riduce i costi di manutenzione, ma può ridurre i rischi per la sicurezza e per gli audit se realizzato in modo strutturato.

    Processo di rilascio e di esercizio: senza una pipeline pulita il refactoring diventa costoso

    Molti progetti legacy Delphi soffrono meno per il codice che per il processo: i build variano a seconda della postazione, i rilasci sono manuali e gli errori non sono tracciabili in modo affidabile. Il refactoring dovrebbe quindi includere sempre la stabilizzazione del processo di delivery.

    Riproducibilità dei build e gestione delle configurazioni

    Dal punto di vista dell’amministrazione e degli audit è importante che un rilascio sia riproducibile: stesse sorgenti, stesse versioni di compiler/librerie, stesse dipendenze. Ciò include configurazioni chiaramente separate per sviluppo, test e produzione (es. endpoint del database, livelli di logging, feature flag).

    Logging, monitoring e capacità di supporto

    „È successo qualcosa“ non basta in esercizio. Il refactoring è un’opportunità per introdurre logging uniforme: voci di log strutturate, codici di errore univoci, contesto (utente, mandante, operazione, interfaccia) e chiara separazione tra errori tecnici e validazioni funzionali.

    Per processi prossimi al 24/7 sono inoltre utili:

    • Health Checks (es. connessione al database, accumulo nella coda, utilizzo memoria),
    • Allertamento per grado di gravità,
    • Runbooks per il riavvio e per le anomalie tipiche.

    Un piano di refactoring praticabile in 6 fasi

    Affinché il refactoring non si perda nelle attività quotidiane, aiuta un piano chiaro compatibile con i cicli di rilascio. Un approccio collaudato:

    1. Creare una mappa dei rischi e delle modifiche (moduli, interfacce, dati, esercizio).
    2. Stendere una rete di protezione: standard di logging, primi test di regressione / golden-master per i percorsi critici.
    3. Tracciare linee di separazione architetturale: livello di servizio e incapsulamento dell’accesso ai dati come «nuova normalità» per le modifiche.
    4. Rifattorizzare gli hotspot: i moduli che vengono modificati frequentemente e causano guasti (utilizzare statistiche degli errori e la cronologia delle modifiche).
    5. Consolidare l’accesso ai dati: uniformare FireDAC/transazioni/time-out, misurare le prestazioni, verificare i deadlock.
    6. Aprire percorsi di modernizzazione: interfacce (REST), tematiche di piattaforma (Unicode/64 bit), modernizzazione graduale dell’UI dove sensato.

    Il nucleo è l’ordine: prima trasparenza e messa in sicurezza, poi interventi strutturali e infine ristrutturazioni più ampie. In questo modo la soluzione resta rilasciabile e stabile in esercizio.

    Quando il refactoring non basta: segnali per una modernizzazione più ampia

    Ci sono situazioni in cui il solo refactoring non risolve il collo di bottiglia. Segnali tipici:

    • Blocchi tecnologici: driver di database non più supportati, componenti non patchabili, dipendenze rigide a 32 bit.
    • L’architettura non è più adeguata: p. es. l’applicazione deve essere gestita come una landscape di servizi, ma tutto è centrato sull’interfaccia utente.
    • Scalabilità e disponibilità: requisiti di multi-tenancy, alta disponibilità o accesso remoto si possono soddisfare solo con cambiamenti strutturali.
    • Requisiti di sicurezza: autenticazione/SSO, audit, crittografia non possono essere integrati a posteriori senza un ampio rifacimento.

    Anche in questi casi il refactoring è spesso una componente sensata: crea ordine per estrarre in modo mirato parti del sistema, invece di sostituire l’intero sistema in una sola volta.

    Conclusione: il refactoring come responsabilità tecnica durante l’esercizio operativo

    Rifattorizzare codice legacy in Delphi è soprattutto una questione di definizione delle priorità, gestione del rischio e vicinanza all’operatività. Se si parte da una ricognizione solida, si mettono in sicurezza i punti critici, si consolidano accesso ai dati e linee di separazione dell’architettura e si indirizzano test e logging sui percorsi critici, da „riordino“ nasce un progetto di modernizzazione controllabile. Il risultato non è solo codice più leggibile, ma un sistema che può essere gestito con maggiore affidabilità, modificato con maggior sicurezza e integrato più facilmente.

    Se desiderate stabilizzare o modernizzare in modo strutturato la vostra soluzione esistente Delphi, definiamo volentieri insieme la situazione di partenza, i rischi e un percorso di rifattorizzazione realistico:

    Nel contesto specialistico rivestono inoltre un ruolo importante la Delphi modernizzazione e il Delphi rifattorizzazione quando integrazioni, flussi di dati e ulteriore sviluppo devono interagire in modo coerente.

    Discutere progetto o intervento di modernizzazione con Net-Base.

    Passo successivo

    Quando un tema diventa un progetto reale, architettura, patrimonio esistente e operatività dovrebbero essere considerati insieme fin dall'inizio.

    Non forniamo solo supporto per questioni isolate, ma anche quando da frammenti di codice sorgente, tematiche legacy o idee di portale deve nascere un progetto aziendale solido.

    • Stato attuale, stato obiettivo e rischi tecnici vengono valutati insieme.
    • REST, l'accesso ai dati, i portali e il rollout non vengono posticipati a fasi successive.
    • Vede in anticipo quale percorso è sostenibile dal punto di vista economico e operativo.

    Condividi il post

    Condividi direttamente questo articolo

    LinkedIn, X, XING, Facebook, WhatsApp e e-mail sono immediatamente disponibili. Per Instagram predisponiamo direttamente il link e un testo breve.

    E-mail

    Instagram si apre in una nuova scheda. Il link e il breve testo vengono copiati prima negli appunti.