Reportage “Delphi Day 2004”

Questo testo vuole essere un modesto reportage redatto da un partecipante (soddisfatto) del «Delphi Day 2004», evento organizzato da Wintech Italia in collaborazione con Borland, azienda che ha creato e supporta tutt'oggi la comunità Delphi&Dintorni, alla quale partecipano molti programmatori Delphi italiani attraverso il sito e i gruppi di discussione dedicati.

Ho pensato di scrivere questo reportage sia per scolpire nella memoria le informazioni, tecniche e non, circolate nel corso del meeting, sia per consentire a chi non ha potuto partecipare (come successe a me l'anno scorso) di sapere cosa è stato detto.

Un'avvertenza: le affermazioni e gli eventi descritti nel presente reportage possono essere intervallati talvolta da opinioni personali che non mancheranno di essere segnalate. :-)

Giorno 1

Introduzione e presentazione D&D

Il DD2004 si è aperto con una breve presentazione della comunità di Delphi&Dintorni e una panoramica tenuta da Marco Cantù sui servizi di formazione offerti da Wintech Italia, dal sito Web www.delphiedintorni.it e dai relativi newsgroup, argomenti sui quali si tornerà in seguito per una dettagliata e interessante analisi delle tecnologie e soluzioni software impiegate nella realizzazione della nuova versione del portale D&D attiva dal mese di febbraio.

Novità del linguaggio Delphi

In questa presentazione Marco Cantù ha illustrato alcune delle nuove caratteristiche introdotte in Delphi 8; alcune di queste feature sono descritte anche nell'eBook gratuito scaricabile dal sito di Cantù in formato PDF (l'indirizzo è http://www.marcocantu.com/d8ebook/).

Prima di iniziare la presentazione, Marco ha proposto un sondaggio per indagare sulle versioni di Delphi utilizzate dagli sviluppatori presenti, con un simpatico “conto alla rovescia”, partendo da Delphi 8 sino ad arrivare a Delphi 1: è stata rilevata una diffusione più o meno estesa delle versioni 5, 6 e 7 di Delphi, mentre Delphi 8 è stato acquistato da poche persone e pochissime, tra queste, lo adoperano assiduamente. Tutto ciò forse è un effetto provocato dall'incertezza, più o meno giustificata, dei programmatori Delphi verso le decisioni di Borland a fronte dell'avvento del criticato .NET Framework di Microsoft, incertezze alle quali ha cercato di fare chiarimenti in seguito David Intersimone, più noto come David I, ospite d'eccezione dell'evento, Vice President e Developer Relations Chief Evangelist di Borland. Dopotutto, Cantù ha sottolineato che il linguaggio presente in Delphi 8, pur non avendo subito pesanti modifiche, rappresenta comunque una delle più “grosse rivoluzioni” affrontate.

La prossima release di Delphi (Delphi 9?) consisterà probabilmente in un ambiente di sviluppo unificato in grado di supportare entrambe le piattaforme Win32 e .NET. I programmatori Win32 potranno beneficiare di nuove caratteristiche del linguaggio, presenti oggi nell'edizione orientata al .NET Framework. A questo punto, sorge la domanda: “perché continuare ad utilizzare il linguaggio Delphi?”. La risposta è articolata e viene fornita in parte da Marco Cantù e in parte da David I.

Innanzitutto, viene fatto notare come il linguaggio Delphi abbia sempre precorso i tempi rispetto ad altri linguaggi concorrenti; rispetto a C#, il linguaggio introdotto da Microsoft per lo sviluppo con il .NET Framework, Delphi .NET vanta maggiori funzionalità che verranno affrontate qui di seguito (alle quali probabilmente Microsoft attingerà in futuro, così come ha già fatto in passato).

Il linguaggio Delphi .NET è, a livello di base, identico ai predecessori ed offre possibilità ineguagliate nel porting dei progetti esistenti sulla piattaforma .NET, senza ricorrere all'ausilio di inutili e complessi wizard o altri espedienti, senza rinunciare all'esperienza, alle conoscenze e alle abitudini acquisite in passato nell'utilizzo dell'ambiente stesso.

Vengono poi presentate alcune caratteristiche tecniche del linguaggio Delphi .NET.

Le classi che fanno parte della FCL (Framework Class Library) del .NET Framework, nonché le classi sviluppate autonomamente, sono organizzate all'interno di namespace; il loro funzionamento è simile a quello dei package in Java...in definitiva, il rapporto tra i “namespace” e le classi al loro interno è del tutto affine a quello che lega una cartella ai file che essa contiene. In Delphi .NET, ciascuna unit rappresenta un namespace, identificato dal nome attribuito alla unit stessa. Pare che questa feature abbia subito qualche critica, poiché C# consente di inglobare più namespace all'interno di uno stesso file sorgente. Il mio parere del tutto personale a riguardo è che sia sostanzialmente inutile, anzi decisamente “confusionario” l'introduzione di più namespace all'interno dello stesso file sorgente, pertanto ritengo questo “scoglio” di Delphi facilmente arginabile; forse sarebbe stato più opportuno consentire l'uso di diverse unit separate per comporre un unico namespace, ma nella mia seppur breve esperienza di programmazione con .NET non ho mai sentito nemmeno questa necessità...forse l'abitudine di programmare in Delphi mi ha completamente plagiato. :-)

La politica strettamente object oriented cui fa capo il linguaggio C# non consente di definire funzioni e variabili globali, poiché ciascuno di questi elementi dovrebbe obbligatoriamente far parte di una classe; Delphi continua a supportare tali scritture creando una classe “Unit” per ciascuna unit (namespace) della quale procedure, funzioni e variabili globali divengono membri statici, preservando comunque lo stesso significato e funzionamento delle versioni precedenti di Delphi, a tutto vantaggio del porting.

In Delphi .NET esistono ancora i tipi Variant, a differenza di VB .NET (considerando che gli strumenti Microsoft basati su linguaggi VB ne facevano largo uso), e permane il concetto di “metaclasse” (per intenderci, il tipo di dati espresso attraverso il costrutto class of); sono inoltre disponibili i tipi “insieme” (set of), del tutto assenti in C# e VB .NET.
Il compilatore Delphi sfrutta le caratteristiche del CLR per poter supportare questi tipi di dati “esclusivi” che non sono adoperabili in altri linguaggi: non sono “CLS compliant”.
Il tipo string corrisponde ora al tipo System.String di .NET (un insieme di System.Char, caratteri Unicode), ma continua ad esistere ancora il tipo ShortString per chi avesse la necessità di utilizzarlo.

Una lunga trattazione è stata dedicata al Garbage Collector, croce e delizia dei programmatori. Riassumendo molto brevemente i concetti espressi, approfonditi il giorno seguente da un'ulteriore presentazione sull'argomento, i programmatori Delphi *non* devono rinunciare all'uso del costrutto try...finally per distruggere gli oggetti creati, anzi tale pratica è incentivata poiché garantisce il rilascio di risorse allocate (file, connessioni a database e così via) che potrebbe avere luogo in un momento successivo e non determinabile, continuando ad occupare preziose risorse fino a quando il Garbage Collector non deciderà, in base agli algoritmi che lo governano, che è finalmente giunto il momento di distruggere l'oggetto non più utilizzato.

Attraverso un “meccanismo” (non saprei come definirlo -NdMarcoB) chiamato Class Helper, è possibile aggiungere metodi ad una classe; tale meccanismo è stato sfruttato da Borland per “farcire” l'oggetto System.Object fornito dal CLR (che fa le veci del TObject che conosciamo) con i metodi di cui è comunemente dotata la classe TObject, tra i quali è presente anche il metodo Free da richiamare per la distruzione di un oggetto.

Ritroviamo i metodi Create e Destroy che possono essere estesi nella scrittura di classi derivate; ci sono solamente alcuni accorgimenti da adottare: il costruttore ereditato deve sempre essere richiamato (mentre si poteva evitare nelle classi che discendevano direttamente da TObject).
Rispetto ad altri linguaggi come C#, Delphi consente la creazione di più metodi costruttori facendo precedere, come sempre, il nome del metodo dalla parola chiave constructor, senza la necessità di dotare i metodi di parametri diversi, magari inutili, per differenziarli così come avviene nel linguaggio C# ove ciascun metodo costruttore è riconoscibile dal fatto che reca lo stesso nome della classe, pertanto si possono definire più costruttori solo attraverso overloading.

Analogamente a C#, Delphi supporta l'overload degli operatori; si tratta di una feature molto interessante, soprattutto perché sarà disponibile anche per lo sviluppo di applicazioni Win32. Tutto lascia prevedere che ci sarà forse buona trasportabilità del codice da .NET a Win32 e viceversa.

Oltre a nuove caratteristiche, vi sono anche delle “dropped features”: data la natura “gestita” (managed) dell'ambiente di esecuzione .NET, l'aritmetica di puntatori non è più ammessa; inoltre, non è possibile introdurre codice assembly in linea ne usare il tipo file of <type>.

Una descrizione dettagliata delle nuove caratteristiche del linguaggio Delphi si trova nell'eBook di Marco Cantù (in lingua inglese) accennato all'inizio.

InstantObjects

In questa presentazione, Carlo Barazzetta (carlo@cibisoft.com) ha parlato di InstantObjects, un “Object Persistence Framework” (OPF) disponibile per Delphi (versioni 5, 6 e 7) e Kylix; realizzato da Seleqt, è stato rilasciato alla comunità OpenSource ed ora è disponibile al sito www.instantobjects.org.

Un OPF è uno strato software (layer) che si frappone tra gli oggetti che formano il “business model” dell'applicazione e i “mezzi di storage” utilizzati per il salvataggio dei dati.

L'uso dei componenti per l'accesso ai dati incorporati in Delphi (i DataSet, in generale, e gli egregi discendenti quali TTable, TADOTable, TIBTable, TQuery e così via) costringono quasi sempre lo sviluppatore ad abbandonare i benefici della programmazione orientata agli oggetti, centralizzando eccessivamente componenti e codice all'interno di singoli Data Module oppure disperdendo righe di codice identiche in unit differenti per replicare letteralmente lo stesso tipo di controllo di validità sugli stessi dati. Inoltre, l'adozione dei componenti BDE, ADO, IBX aumenta la dipendenza del codice dell'applicazione verso la piattaforma di accesso ai dati utilizzata.

Gli OPF intervengono in questo scenario fornendo classi che possono essere utilizzate dallo sviluppatore per creare discendenti modellando le classi degli oggetti che sono coinvolti nell'attività dell'applicazione (vengono creati o caricati, modificati, salvati e infine distrutti); le classi del framework non forniscono solamente il supporto alla “persistenza” degli oggetti, cioè alla loro possibilità di essere memorizzati fisicamente in un dispositivo di storage, ma integrano anche strumenti per l'enumerazione e l'esposizione di tali oggetti affinchè sia possibile rappresentarli senza troppa fatica (leggi: con poche righe di codice) attraverso un'interfaccia utente.

Attraverso InstantObjects, lo sviluppatore può modellare le classi che rappresentano i dati da trattare all'interno dell'applicazione; utilizzando una finestra denominata “Model Explorer” si possono visualizzare, aggiungere e modificare le classi, definendo quali unit sono destinate a contenerle.
Intervenendo visualmente sulle classi mostrate nel Model Explorer, viene generato e modificato il codice sorgente (e viceversa).

Esistono poi componenti (InstantSelector e InstantExposer) che si occupano di esporre gli oggetti attraverso dei DataSet consentendo così di utilizzare i controlli “data aware” (Data Controls) già inclusi in Delphi per o di terze parti per editare i dati. Con il componente InstantSelector è anche possibile “caricare” un set di dati dal database utilizzando un linguaggio “simil SQL”.
L'uso del DataSet è limitato solo a questa evenienza: non si devono codificare eventi OnValidate e affini, poiché tutta la logica è contenuta nel codice delle classi generate dal framework e modificabili.

Un simile approccio permette allo sviluppatore di concentrarsi maggiormente sulle classi che costituiscono la logica dell'applicazione, slegandosi il più possibile dal sistema di storage sottostante e ottenendo codice portabile, riutilizzabile e drasticamente semplificato (poiché le ridondanze vengono eliminate).

A fronte di innegabili vantaggi esistono anche “controindicazioni” nell'uso di InstantObjects: le caratteristiche peculiari fornite da alcuni database, per via della forte astrazione del framework rispetto alla base dati utilizzata, sono inaccessibili e le prestazioni generali potrebbero subire una leggera flessione rispetto ad applicazioni ben progettate che utilizzano componenti nativi. Inoltre, un uso proficuo degli OPF richiede una buona conoscenza e padronanza della programmazione ad oggetti, pertanto la curva di apprendimento è tendenzialmente ripida.

Il codice sorgente di InstantObjects è organizzato in più package, di cui uno contiene classi e componenti che formano il “nucleo” (Core) del framework e più package che contengono i “broker”, cioè i componenti che consentono di interfacciarsi alle tecnologie e alle piattaforme di accesso ai dati più diffuse (ADO, IBX, dbExpress, ecc.) per la memorizzazione (persistenza) dei dati.

La presentazione di InstantObjects si è snodata per la maggior parte sulla dimostrazione pratica di come si utilizza il framework nella creazione di un progetto; la dimostrazione è disponibile sottoforma di video introduttivo, scaricabile dalla homepage di InstantObjects sul sito SourceForge.net. Carlo ha inoltre suggerito a chi si avvicina per la prima volta al framework di esaminare con attenzione il progetto di nome “Primer” distribuito con il package stesso.

Al termine della presentazione è intervenuto Carlo Wolter, Project Manager del progetto OpenSource di InstantObjects, che ha mostrato l'intensa attività attorno al progetto stesso che coinvolge, per la maggior parte, sviluppatori italiani. Si sta lavorando molto sul miglioramento delle prestazioni con l'obiettivo di avere una nuova versione più performante a settembre.

Infine, nei newsgroup Delphi&Dintorni esiste un'area dedicata a InstantObjects in lingua italiana, un buon punto di partenza per chi intende iniziare ad utilizzarlo, per chiedere aiuto o consigli.

Le novità di .NET Framework 2.0 (Visual Studio 2005)

In questa presentazione, Francesco Albano (Senior .NET Architect in Microsoft Italia) ha mostrato alcune delle caratteristiche della prossima versione del .NET Framework, la 2.0, soprannominata “Whidbey”.

Attraverso alcune slide, è stato evidenziato come il .NET Framework sia parte integrante di un percorso di migrazione da un API rappresentata da funzioni a una collezione di componenti e servizi, il tutto per semplificare notevolmente il ciclo di sviluppo del software, nonché fornire uno strato che garantisca maggiore sicurezza (tema alquanto “spinoso” per Microsoft) non solo nell'ambito del Web.

.NET 2.0 (Whidbey) manterrà i “pilastri principali” della versione attuale, come Windows Forms (per realizzare interfacce grafiche in Windows) e ADO .NET (che avrà orientamenti verso Yukon, la nuova versione “in cantiere” di SQL Server). La piattaforma sarà presente, come previsto, su diversi tipi di dispositivi quali SmartPhone, PDA e macchine a 64bit, con maggiori performance soprattutto per quanto riguarda l'interoperabilità (P/Invoke) verso COM. Infine, il framework includerà Object Spaces, un Object Persistence Framework (OPF).

All'introduzione generale ha fatto seguito una dimostrazione pratica delle caratteristiche del nuovo ambiente di sviluppo integrato Visual Studio 2005 (in versione prealpha), della quale riassumo i dettagli salienti qui di seguito.

Innanzitutto, sono stati apportati notevoli miglioramenti al mondo di ASP .NET: la collezione dei controlli Web disponibili è stata ampliata con nuovi componenti (maschera di login, mappa automatica del sito, ...) e ciascun controllo Web è a tutti gli effetti anche un controllo Mobile, cioè è in grado di restituire una rappresentazione grafica ottimale su dispositivi mobili.
Per verificare il corretto funzionamento delle pagine ASP .NET, è possibile sfruttare un Web server integrato all'ambiente di sviluppo, senza doversi appoggiare ad IIS o ad altri Web server addizionali. Inoltre, un wizard completo consente di personalizzare in modo intuitivo la configurazione dell'applicazione Web modificando automaticamente il file Web.config.

In generale, per ogni applicazione .NET è possibile definire le opzioni di sicurezza degli assembly a cui fa riferimento (produttore, versione, provenienza...) per l'esecuzione del solo codice che si ritiene valido, sicuro e certificato.
Il deploy è di gran lunga semplificato: è sufficiente avere il framework installato. Le componenti aggiuntive eventualmente scaricabili attraverso la rete sono soggette alle policy di sicurezza impostate, con la possibilità di eseguire l'applicazione all'interno di una “sandbox” con diritti limitati. Un'applicazione può essere pubblicata semplicemente copiando i file necessari in una directory virtuale; il client che scarica i componenti dell'applicazione si occuperà di controllare tutte le impostazioni di sicurezza necessarie.

A livello di ambiente di sviluppo, Visual Studio 2005 include strumenti di “code refactoring” ed è in grado di costruire progetti di test (funzionali, di carico, ecc.) per lo “stress” delle applicazioni, dotati di performance counter e performance monitor gestiti da classi con le quali è possibile interoperare.

Infine, Visual Studio 2005 include la gestione dello sviluppo in team, permettendo la definizione degli utenti e dei progetti da completare; l'utente “manager” controlla lo stato di avanzamento dei progetti, mentre l'ambiente regola le operazioni di “check in/out”, contrassegna i test già effettuati e così via.

In definitiva, la prossima versione di Visual Studio fornirà nel 2005 ciò che Borland fornisce ora con i propri tool di sviluppo (Delphi, JBuilder, C#Builder...) affiancati da CaliberRM o StarTeam e OptimizeIt Profiler. :-)

D&D Team: Tecnologie D&D

Devo ammettere che questa presentazione solleticava parecchio la mia curiosità poiché, dopo aver sviluppato un'applicazione Delphi interamente basata sulla posta elettronica, mi stavo interessando in questi ultimi periodi alla creazione di un news server con i componenti Indy; non mi sembrava una cosa eccessivamente complicata, perciò mi sono buttato a capofitto nella lettura di RFC varie per mettermi avanti...anche perché prodotti (commerciali e non) che mi dessero soddisfazione ne ho trovati pochi.

Ero quindi smodatamente curioso di conoscere il percorso intrapreso dalla community Delphi&Dintorni nella realizzazione di un nuovo news server “fatto in casa”, da sostituire al server precedente che aveva provocato un numero imprecisato di problemi a causa dell'elevato numero di messaggi complessivamente raggiunto.

Andrea Magni ha presentato attraverso una serie di slide il processo di creazione del server NNTP sul quale sono attualmente ospitate le discussioni della community Delphi&Dintorni; gran parte del codice è stato scritto da Andrea Magni, con la stretta collaborazione di Paolo Rossi, Nando Dessena e Uberto Barbini.

Il progetto è stato realizzato con Delphi 7 e Kylix, utilizzando i componenti Indy (sito ufficiale: http://www.indyproject.org) per quanto riguarda la gestione delle connessioni TCP, i componenti UIB (Unified InterBase, sito ufficiale: http://www.progdigy.com/UIB/) per la connessione ad un database server FireBird versione 1.5 (sito ufficiale: http://www.firebirdsql.org/); il sistema operativo sul quale gira attualmente il news server è Linux.

Le prerogative del progetto sono la portabilità, robustezza, discreta apertura, leggerezza e facilità nella configurazione (attraverso file INI e via Web); una soluzione di questo tipo consente inoltre di espandere le funzionalità del sistema aggiungendo regole per la validazione dei messaggi, personalizzando le informazioni memorizzate nei log, introducendo estensioni non previste dal protocollo standard e così via.

Alcuni schemi e diagrammi UML hanno presentato la strutturazione interna del sistema, evidenziando lo sforzo di separare la logica che governa la gestione delle richieste, il reperimento e il salvataggio dei dati e l'autenticazione, evitando di legarsi agli eventi forniti dai componenti e implementando interfacce e classi ad hoc. L'intercambiabilità dei componenti è uno dei punti fermi in sede di progettazione dell'intera architettura. Esiste una gerarchia di classi affollata che gestisce le richieste provenienti dai client collegati (autenticazione, accesso ad un determinato gruppo, richiesta di un primo messaggio, consultazione del messaggio successivo, reperimento dei nuovi messaggi, ecc.). Una interfaccia definisce i metodi corrispondenti alle azioni comuni che vengono eseguiti dai client e un apposito thread la implementa, derivando dalla classe TIdPeerThread che appartiene al package Indy e rappresenta il thread di lavoro per i componenti server TCPServer in genere; ciascun thread mantiene inoltre informazioni sullo stato della sessione quando il client è connesso al server, memorizzando i dati del client, incluse le sue “credenziali” (nome utente e password) per l'autenticazione (utili, ad esempio, per nascondere o negare l'accesso a gruppi di discussione privati).

Citando qualche dato prettamente tecnico, l'eseguibile del news server ha una dimensione che si aggira attorno ai 400KB, ospita più di 30 gruppi di discussione (a cui la comunità D&D partecipa ogni giorno) e conteneva già più di 4000 messaggi (a partire dal 1° di febbraio).

Infine, per il sito Delphi&Dintorni (http://www.delphiedintorni.it) è stato costruito un efficiente “front-end” in grado di reperire i thread memorizzati all'interno dei newsgroup (anche quelli pubblici come “it.comp.lang.delphi”) e presentarli al visitatore, con ampia disponibilità di opzioni per la visualizzazione, l'ordinamento e il filtraggio dei messaggi. Attraverso il sito, è possibile inoltre consultare varie notizie reperite attraverso RSS Feed, un formato XML al quale viene poi applicato un foglio di stile XSL per la visualizzazione formattata all'interno del sito Web.

Discussioni a tema

Il tempo per le “discussioni a tema” è stato un po' tiranno, ma comunque produttivo; purtroppo, posso solo relazionare quanto è emerso dal gruppo al quale ho partecipato che incentrava le discussioni a ruota libera sull'argomento “IntraWeb vs ASP .NET”, reso attivo dai “direttori d'orchestra” Gabriele Giacomelli e Paolo Rossi.

Concettualmente, IntraWeb ed ASP .NET non differiscono di molto: si tratta di due tecnologie pensate per consentire allo sviluppatore di creare applicazioni per il Web in modalità RAD, cioè trascinando i controlli visuali all'interno di una WebForm (al posto di una Windows Form) i quali vengono restituiti ad un browser (o ad un client generico) attraverso una pagina HTML; un'interazione dell'utente (ad esempio, il clic su un pulsante) provoca l'esecuzione lato server del codice inserito per la gestione degli eventi il quale modifica lo stato degli oggetti che rappresentano i controlli visuali presenti sul WebForm; la pagina Web che viene restituita al client riporta l'aspetto dei controlli modificato.

Le domande più frequenti erano riferite al problema del “deploy” utilizzando l'una o l'altra tecnologia. IntraWeb è un framework che genera contenuto HTML all'interno di una Web Server Application di Delphi; questo rende IW particolarmente utilizzabile nella realizzazione di applicazioni ed estensioni per tutti i tipi di web server, portabili ed adoperabili sia su Windows che su Linux, mentre ASP .NET rimane (almeno per il momento) una soluzione disponibile solo per ambienti Windows.
C'è da notare che alcuni web server (come IIS) mantengono in una cache le estensioni (ad esempio, le DLL ISAPI), quindi il “deploy” viene reso può diventare problematico per l'impossibilità di aggiornare o cancellare la DLL che risulta apparentemente bloccata, specialmente quando il provider fornisce un servizio di hosting che non consente il controllo remoto del server. Per quanto riguarda ASP .NET, il deploy è molto semplice: basta copiare gli assembly (DLL in linguaggio intermedio) nella cartella “bin” della directory virtuale corrispondente al proprio sito per ottenere automaticamente l'avvio dell'applicazione aggiornata con il caricamento automatico delle nuove componenti.
Alcuni provider (ad esempio, Aruba) che forniscono hosting su sistemi operativi Windows Server 2003 impedisco l'uso di eseguibili (CGI, ISAPI, ...) mentre acconsentono l'adozione di ASP .NET, forse per la maggiore gestibilità delle opzioni di sicurezza fornite dal framework.

Dal punto di vista delle prestazioni, i pacchetti si equivalgono, poiché si tratta in entrambi i casi di codice nativo che viene eseguito dalla CPU.

IntraWeb rappresenta una soluzione prettamente “per sviluppatori”: il suo utilizzo è possibile solamente all'interno di Delphi (se consideriamo l'edizione Win32): richiede quindi uno sviluppatore Delphi per poter essere adoperato e non è progettato per agevolare la cooperazione tra web designer e web developer, cioè tra chi ha il compito di disegnare la parte visuale di un sito Web e chi deve codificarne il funzionamento; ASP .NET, invece, consente di separare la parte visuale in linguaggio HTML (che contiene solo riferimenti ai controlli Web presenti nella pagina) dal codice che la governa e ne gestisce gli eventi (la tecnica è denominata “code behind”).

IntraWeb risulta più facile da utilizzare per chi ha familiarità con la libreria VCL .NET e le funzioni della RTL di Delphi, mentre ASP .NET si appoggia sulla Framework Class Library di .NET, probabilmente preferita da chi sviluppa anche applicazioni Windows con la libreria Windows Forms, oppure sviluppa con il .NET Framework adoperando altri linguaggi e/o ambienti di sviluppo.

Ovviamente, non credo che lo scopo della discussione fosse di trovare lo strumento migliore tra IntraWeb e ASP .NET (anche perché penso che ogni strumento vada valutato nell'ambito in qui viene applicato), quanto più di chiarire i vantaggi e i problemi derivanti dall'una o dall'altra soluzione (che spero di aver sintetizzato in modo accurato ed esaustivo). :-)

The Future of Delphi

Si tratta sicuramente di una delle presentazioni tra le più interessanti in cui David Intersimone, più noto come David I, ha chiarito qualche dubbio sul futuro dell'ambiente di sviluppo Delphi (probabilmente il preferito di chi sta leggendo) dopo aver scattato qualche “foto ricordo” alla platea incuriosita. :-)

La presentazione si è aperta con una diapositiva raffigurante la “timeline” dell'evoluzione del Turbo Pascal, dalla sua nascita nel 1983 sino alle edizioni più recenti che sono state poi sostituite da Delphi nel 1995. Qui di seguito, è riportata la timeline di Delphi:

1995

Delphi 1.0 – Win3.1, PME, VCL, database

1996

Delphi 2.0 – Win32, optimizing compiler

1997

Delphi 3.0 – Com, Internet

1998

Delphi 4.0

1999

Delphi 5.0

2000

Delphi 6.0

2001

Kylix (Delphi for Linux)

2002

Delphi 7.0 for Win32/Linux, Bold

2003

Delphi 8.0 for .NET – IL, ECO

2004

Delphi 7 and 8 updates

La rivisitazione della storia di Delphi è stata accompagnata da qualche “chicca”: copertine di riviste dedicate alla programmazione e uno spot pubblicitario in cui una coppia di tedeschi, in pieno Ocktoberfest, discutono lucidamente sulle potenzialità di Delphi, con l'intromissione di una cameriera che sottolinea il vantaggio del supporto alla programmazione orientata agli oggetti.

David I ha precisato la posizione di Borland per rispondere al clamore e alle polemiche sorte per l'insinuazione del .NET Framework di Microsoft all'interno di molti prodotti Borland, tra i quali vi è anche Delphi.

Riguardo il vociferare di “rapporti intimi” tra Borland e Microsoft, David I ha replicato facendo notare come la partnership con il produttore del sistema operativo per il quale si costruisce un compilatore sia necessaria; la collaborazione tra Borland e Microsoft non è cosa nuova, ma dura da anni, da quando la Borland ha deciso di produrre tool di sviluppo per MSDOS, passando poi alla piattaforma Win32 sino ad arrivare al .NET Framework.

Nella visione Microsoft dell'evoluzione dei propri sistemi operativi, il .NET Framework rappresenta uno dei cardini, pertanto è fondamentale dal punto di vista Borland dotare i propri ambienti di sviluppo del supporto a questa piattaforma per consentire ai programmatori di continuare, se lo desiderano, a sviluppare su sistemi Windows.

Tuttavia, a differenza di Microsoft, Borland basa il proprio business sulla fornitura di strumenti per sviluppatori; al contrario, Microsoft concentra i propri sforzi commerciali sui sistemi operativi della famiglia Windows e sulla suite Office. Ciò significa che gli ambienti di sviluppo Microsoft sono maggiormente incentrati a “spingere” gli sviluppatori di software verso le proprie piattaforme adottando tecnologie proprietarie; al contrario, Borland non ha alcun particolare ambiente di esecuzione da promuovere, ma persegue l'obiettivo di fornire quanti più strumenti di sviluppo possibile indirizzando genericamente i sistemi operativi e le piattaforme esistenti.
Infatti, Borland non sostiene partnership unicamente con Microsoft; ad esempio, intrattiene rapporti con Sun per lo sviluppo di soluzioni per la piattaforma Java (JBuilder).

Basta pensare al trattamento subito da Visual Studio: con l'introduzione della piattaforma .NET, gli sforzi di Microsoft nel campo degli ambienti di sviluppo RAD sono stati interamente rivolti a Visual Studio .NET, abbandonando (quasi) completamente la controparte Win32 (versioni 6 e precedenti). In poche parole, chi vuole sfruttare le conoscenze acquisite con Visual Basic, ad esempio, deve affrontare un porting senza precedenti adattandosi al cambio radicale imposto dal linguaggio VB .NET, probabilmente apprendendo nuove metodologie di programmazione (OOP) e una sintassi completamente diversa dall'edizione precedente del linguaggio.

David I ha dichiarato che i cambiamenti al sistema operativo Windows verranno affrontati mantenendo il supporto alla piattaforma Win32 fino a quando i programmatori lo riterranno necessario, cioè fino a quando Win32 continuerà ad essere utilizzata e utilizzabile, sino al momento della sua completa sparizione; l'attenzione verso Win32 è stata solamente surclassata dall'eccessivo clamore generato dall'apparizione del .NET Framework. Lo stesso dicasi per quanto riguarda la libreria VCL .NET: essa garantisce non solo uno strato indipendente verso il .NET framework, ma un livello di astrazione su qualsiasi cambiamento dovesse avvenire nel passaggio dai sistemi operativi attuali fino al tanto temuto Longhorn e oltre (si parla di piattaforme non preventivabili al momento).

A proposito di Delphi per Win32, come anticipato all'inizio del reportage, è probabile che alcune feature presenti nell'attuale Delphi .NET vengano rese disponibili anche per lo sviluppo di progetti Win32; di certo, non verrà replicata alcuna funzionalità di “garbage collection” o esecuzione gestita (managed) del codice.
Le feature che hanno maggiore probabilità di comparire nel mondo Win32 sono l'overload degli operatori (ciascuna classe può personalizzare l'applicazione degli operatori alle relative istanze), i “nested types” (si definiscono tipi e costanti incorporate all'interno di una dichiarazione di classe), i “record methods” (i record possono contenere metodi come le classi, ma vengono allocati nel modo convenzionale a cui siamo abituati), “custom attributes” (attributi personalizzati associabili a classi e identificatori per ottenere informazioni a runtime in modo similare alla RTTI), “multicast events” (è possibile agganciare più metodi di gestione ad uno stesso evento).

Queste ed altre feature sono descritte in modo più dettagliato all'interno dell'ebook “Essential Delphi for .NET” di Marco Cantù, citato all'inizio del reportage.

La presentazione si è conclusa con una sessione di domande e risposte; la più “spinosa” (e la più frequente) riguarda la disponibilità del .NET CompactFramework per lo sviluppo su PocketPC all'interno di Delphi; David I ha voluto precisare che sebbene il CompactFramework sia uno strumento interessante per lo sviluppo Mobile, esistono altre piattaforme ben più diffuse rispetto ai PocketPC soprattutto nel campo della telefonia (ad esempio, Symbian), pertanto prima di prendere accordi sul CompactFramework, Borland preferisce valutare attentamente le possibilità di accordi con altri partner. La sentenza finale riguardo il CompactFramework, tuttavia, è stata «available as soon as possible».

Nel breve tempo che ha portato alla conclusione del primo giorno del Delphi Day 2004, David I ha giocherellato con il compilatore Turbo Pascal 1.0...stupendosi del fatto che, a volte, è talmente veloce da iniziare la compilazione prima ancora che venga premuto l'apposito tasto. :-)
Il compilatore Turbo Pascal (e altri “antichi” software) sono disponibili nell'area “Museum” del sito dedicato alla community di Borland (http://community.borland.com); ben presto saranno pubblicate altre “chicche” riguardanti Delphi.

Giorno 2

ALM “Alive”

La seconda giornata si è aperta con una serie di presentazioni a taglio prevalentemente commerciale. La prima di queste, tenuta da David I, ha descritto in dettaglio la soluzione ALM (Application Lifecycle Management) di Borland.

Borland estende i propri tool di sviluppo integrando strumenti che, pur essendo incentrati sullo sviluppo, ricoprono altre problematiche in merito al ciclo di vita del software, permettendo di spostarsi tra le varie fasi del ciclo di sviluppo, dalla progettazione all'implementazione e viceversa; la soluzione ALM soddisfa questi requisiti nella loro totalità.

Inoltre, come preventivato nella presentazione «Future of Delphi», Borland cerca di favorire l'adattamento del “developer” alla mutazione delle piattaforme esistenti e alle varie soluzioni fornite da vendor differenti, tenendo conto del fatto che molti sviluppatori ricoprono spesso altri ruoli (architettura del software, deploy e così via).

Alcuni vendor “forzano la mano” su tecnologie proprietarie, Borland invece cerca di fornire quante più soluzioni possibili indirizzando genericamente le piattaforme più diffuse. Borland sfrutta inoltre diversi “studi di settore” aperti (ad esempio, CMMI, di cui si può sapere di più al sito http://www.sei.cmu.edu/cmmi/) che misurano il grado di qualità nello sviluppo del software integrandone le linee guida all'interno dei tool di sviluppo.

I tool ALM-oriented aumentano la collaborazione tra sviluppatori e manager; questi ultimi definiscono gli aspetti del sistema, mentre i primi hanno l'incarico di implementarli. Questo processo verrà esaminato in dettaglio nella presentazione di CaliberRM.

Per quanto riguarda il futuro della soluzione ALM, Borland si concentrerà su processi e metodologie software, business processes, team di sviluppo e progetti e architetture riusabili, poiché è convinzione di Borland che il “buon software” nasca dalla corretta gestione del ciclo che porta alla sua produzione, meccanismo sul quale altri vendor non forniscono il supporto necessario. Per fare un esempio triviale, è possibile far divenire un word processor un ambiente di sviluppo per applicazioni introducendo al suo interno un opportuno linguaggio di programmazione, ma senza la possibilità di gestire correttamente i requisiti, definire le specifiche da implementare, eseguire test di performance e funzionalità, risulta difficile produrre un software che possa definirsi di qualità.

Maggiori informazioni su ALM si trovano nella pagina relativa sul sito Borland: http://www.borland.com/alm/.

CaliberRM e StarTeam

Nell'attività di sviluppo di un software è stato dimostrato come una cattiva definizione dei requisiti iniziali di un sistema sia capace di provocare ingenti danni e perdite, derivanti dalla necessità di correggere difetti e rivedere i requisiti del prodotto stesso in corso d'opera, culminando a volte nel caso peggiore di dover ricominciare da capo.

Si potrebbe dire che, analogamente a quanto si afferma nel campo medico, “prevenire è meglio che curare”: correggere sin da subito eventuali difetti nella definizione della terminologia da utilizzare per descrivere gli eventuali elementi di un sistema e comprendere (accertandosi che tutti gli altri abbiano compreso) le caratteristiche che il sistema stesso dovrà avere riduce il costo delle revisioni successive.

David I, in questa presentazione dedicata a CaliberRM, sottolinea e sintetizza questo problema con un semplice slogan: “Fail to plan, plan to fail”, e descrive apertamente i problemi derivanti dai metodi convenzionali usati nella definizione dei requisiti di un software, quali appunti scritti durante un meeting, messaggi di posta elettronica slegati tra loro, oppure il classico documento di testo nel quale spesso si omettono, durante la stesura, informazioni riguardanti l'autore, la data di creazione e altro ancora. Si tratta insomma di “pratiche” che portano facilmente ad un errata, incompleta o poco accurata definizione dei requisiti iniziali di un progetto.

Il tool CaliberRM si inserisce in questo frangente e copre la fase “Define” (definizione) del ciclo ALM coadiuvando i manager di progetto nel difficile compito della gestione e manutenzione dei requisiti che il software, implementato dagli sviluppatori, deve soddisfare.

Ciascun manager definisce e modifica i requisiti dei quali può tenere traccia e verificare, passo dopo passo, a che punto è la loro implementazione.

Per dirla in modo scherzoso, è sempre possibile risalire su «chi ha detto cosa» (utile agli sviluppatori in caso di “controversie”), sebbene non sia possibile “attaccarsi” al «non mi è stato detto» (utile invece ai project manager). :-)

Tutte le informazioni dettagliate su CaliberRM si trovano sul sito Borland: http://www.borland.com/caliber/.

La seconda parte della presentazione ha riguardato le problematiche dello sviluppo in team che, oltre alla definizione dei requisiti, introduce nuove problematiche relative al controllo del processo di sviluppo in senso stretto, alla gestione di versioni differenti, all'individuazione di difetti nel software e alla loro risoluzione ottenuta anche mediante la comunicazione facilitata tra i membri del team di sviluppo.

In questo contesto si inserisce StarTeam, prodotto che ricopre la fase “Manage” della soluzione ALM di Borland.

StarTeam è un tool che fornisce un “repository centrale” nel quale convergono tutti gli elementi che definiscono un progetto, quali i requisiti da soddisfare, le modifiche da apportare e la traccia completa, con versioning, dei file che sono stati creati, aggiornati o cancellati; pur somigliando ad un comune CVS, occorre precisare che StarTeam lavora in modo interattivo occupandosi di mantenere aggiornato il repository in base alle modifiche apportate senza dover necessariamente invocare operazioni di “check in” e “check out”.

Tutte le informazioni sono conservate in un “luogo sicuro”, al quale è possibile accedere fornendo credenziali (username e password) configurabili dall'utente delegato all'amministrazione del sistema.

Le informazioni dettagliate su StarTeam si trovano sul sito Borland alla pagina http://www.borland.com/starteam/.

ECO – Enterprise Core Objects

In questa sessione Jason Vokes, Product Manager del settore RAD di Borland Europe, ha presentato la soluzione ECO (Enterprise Core Objects), RMDA (Rapid Model Driven Architecture) disponibile per C#Builder e Delphi 8.

E' possibile paragonare ECO ad un OPF (di cui si è già parlato) ma decisamente più avanzato, attraverso il quale è possibile modellare la “business logic” della propria applicazione, cioè interagire con diagrammi visuali intuitivi definendo la struttura delle classi rappresentanti i dati da trattare e il modo in cui viene fornita loro persistenza, cioè il mezzo e le modalità con cui i dati vengono poi salvati all'interno di un dispositivo di storage (ad esempio, un database).

Trattandosi di una rappresentazione visuale, il modello rende più semplice comprendere il modo in cui è stato strutturato un progetto anche molto complesso grazie alla maggiore astrazione.

Jason Vokes si è dedicato ad una “dimostrazione pratica”, disponibile anche sul sito Borland nella sezione dedicata ai tutorial di Delphi 8 basati appunto su ECO: http://www.borland.com/delphi_net/architect/eco/tutorial/; pertanto, evito la descrizione passo per passo di tale esempio e cito solo le caratteristiche salienti, anche perché ho avuto non poche difficoltà a seguire le parole di Jason. :-)

Per utilizzare ECO, è necessario creare una “ECO Windows Forms Application”; il nome è già sufficiente per indicare che ECO è utilizzabile con la piattaforma Windows Forms, cioè la libreria di classi Microsoft per la creazione di applicazioni Windows con il .NET Framework, ma apparentemente non con la libreria VCL .NET.

ECO consente di modellare le classi dei dati attraverso il linguaggio UML (Unified Modelling Language).

La finestra “Model View” di Delphi 8 riporta le unit per le quali è possibile definire un modello; il modello viene completato in un apposita finestra sfruttando i tool forniti dalla “Tool Palette” (l'equivalente della Component Palette di Delphi 7 e precedenti) che, magicamente, si trasforma rendendo disponibili gli elementi introducibili all'interno del diagramma (classi, relazioni e così via).

La costruzione del diagramma si tramuta implicitamente nella stesura di codice: le classi definite visualmente che fanno parte del Business Model (o Domain Model) vengono implementate attraverso classi Delphi direttamente dal framework ECO.

Gli oggetti (le istanze) delle classi definite all'interno di un modello vanno a riempire l'ECOSpace, uno “spazio virtuale” dal quale è possibile, impiegando componenti ECO specifici (selezionabili dalla Tool Palette), estrarre tali istanze ottenendone la visualizzazione all'interno di un'interfaccia utente GUI (ad esempio, un DataGrid o altri controlli che possano essere collegati ad una “sorgente dati”).

E' possibile “aggiungere” oggetti semplicemente richiamando i costruttori di ciascuna classe; se vi sono controlli associati, le proprietà possono essere facilmente definite attraverso tali controlli oppure usando finestre create automaticamente dal framework ECO.

ECO separa egregiamente la definizione del modello dei dati, cioè le classi attraverso le quali vengono gestiti, dal meccanismo di persistenza, cioè dal dispositivo di storage in cui i dati vengono salvati ed eventualmente ricaricati.

Concludendo, ECO viene in aiuto dello sviluppatore nella realizzazione di progetti consentendogli di produrre un modello visuale UML che rappresenti la struttura dati sulla quale opera l'applicazione, sfruttando diagrammi intelligibili e sicuramente più intuitivi del codice “nudo e crudo” (che il framework ECO tende, tra l'altro, a farcire parecchio). I vantaggi derivanti dall'uso di questo tool sono sostanzialmente quelli portati dall'uso di un OPF convenzionale: è possibile concentrarsi maggiormente sulla logica dell'applicazione piuttosto che alla sua infrastruttura, slegandosi maggiormente dal meccanismo con il quale le informazioni verranno poi immagazzinate.

Quando il GC .NET non basta: OptimizeIt Profiler

Il Garbage Collector del .NET Framework è già stato accennato nella presentazione riguardante le novità del linguaggio Delphi; in questa sessione, Gabriele Giacomelli espone ulteriori considerazioni riguardo al meccanismo di Garbage Collection nell'ambiente .NET Framework, valutando le limitazioni di quest'ultimo e descrivendo i possibili accorgimenti.

L'argomento è stato introdotto analizzando la definizione di “memory leak” riportata sul sito MSDN: si tratta di un consumo di memoria dovuto al mancato rilascio di risorse.

In ambiente Win32, il programmatore è il responsabile del rilascio delle risorse utilizzate, direttamente (attraverso apposite istruzioni esplicite) o indirettamente (attraverso meccanismi introdotti dal compilatore). Nell'ambiente “gestito” .NET, è il Garbage Collector che ha questo gravoso compito.

Detto questo, si possono già definire alcuni presupposti: trattandosi di un software scritto da comuni mortali, il GC .NET non è esente da difetti, imperfezioni ed errori, sebbene sia in grado di lavorare in maniera efficiente.

Nell'approccio al .NET Framework, quindi, occorre studiare a fondo (e provare sperimentalmente) il funzionamento di ogni classe, cercando quelle più adatte allo scopo che si intende raggiungere; in altre parole, vi sono molteplici aspetti da conoscere e approfondire prima di intraprendere lo sviluppo con il framework.

Tenendo conto dei meccanismi che regolano il funzionamento del framework (tra cui il GC), si possono verificare cali di prestazioni, eccessiva occupazione di memoria e altri “effetti collaterali” laddove una classe non rappresenti lo strumento ottimale da utilizzare in un determinato ambito.

Per fare qualche esempio, la classe String che contiene una stringa di testo, se usata migliaia di volte in un ciclo di concatenamenti, può rappresentare un “collo di bottiglia” in quanto viene creata una nuova istanza della classe contenente il testo composto ad ogni ciclo. La soluzione? Utilizzare la classe StringBuilder, appositamente progettata a questo scopo.
Considerando il funzionamento del GC .NET, sappiamo che non è possibile determinare con precisione quando un oggetto verrà distrutto. Supponiamo di fare uso di una classe che interagisce con COM oppure con altre risorse di sistema (ad esempio, risorse GDI, connessione a database, ecc.): fino a quando il GC non deciderà di rilasciare l'oggetto alla fine del suo utilizzo, la memoria allocata per tali risorse – estremamente preziosa – rimarrà occupata.

In definitiva, sebbene .NET sia un mondo nuovo, molte cose sono già state viste in passato...nonostante ciò, occorre apprendere l'uso degli strumenti giusti, che sono comunque presenti nel framework, per risolvere i problemi e utilizzarlo al meglio.

Borland ci viene in aiuto con uno strumento, OptimizeIt Profiler, progettato appositamente per individuare diversi tipi di problemi che possono verificarsi all'interno delle applicazioni .NET, problemi che vanno comunque risolti attraverso le proprie conoscenze tecniche che rimangono quindi essenziali. OptimizeIt ricopre la fase “Test” della soluzione ALM e si integra sia in ambienti Borland per .NET, sia in Microsoft Visual Studio .NET.

Senza introdurre codice “speciale” (sebbene sia possibile farlo), OptimizeIt è in grado di “agganciarsi” a qualsiasi applicazione .NET ponendosi in ascolto e segnalando sprechi di memoria, rilevando colli di bottiglia, individuando creazioni (troppo) numerose e massicce di oggetti ed altre situazioni che possono essere considerate anomale.

OptimizeIt rappresenta graficamente la “catena delle chiamate”, evidenziando i punti in cui sono stati riscontrati i potenziali problemi, con la possibilità di posizionarsi esattamente nel punto “incriminato” del codice sorgente (se disponibile); l'analisi può essere esportata per consegnarla a chi di dovere che si occuperà poi di prendere i dovuti accorgimenti ottimizzando il codice o selezionando le classi più adatte al compito da eseguire. Le statistiche raccolte da OptimizeIt possono essere confrontate con i risultati raccolti in sessioni di esecuzione precedenti.

Il “monitoraggio” di un'applicazione .NET con OptimizeIt può essere utile anche solo per verificare come si comporta il CLR durante l'esecuzione...però non so se il costo del prodotto giustifica comunque il suo uso a mo' di giocattolo. ;-)

Sviluppo per dispositivi Mobile

La sessione conclusiva del Delphi Day è stata presenziata da Jason Vokes che ha mostrato alcune delle tecnologie Borland dedicate al mondo dei dispositivi Mobile. Personalmente, speravo di parlasse dello sviluppo Mobile in Delphi, ma la presentazione del giorno precedente sul futuro di Delphi aveva già smorzato le mie aspettative.

Jason Vokes ha fatto notare che spesso la percezione delle applicazioni per dispositivi mobili non è corretta, poiché si tende ad attribuire maggiore o minore complessità alle applicazioni stesse in base alle dimensioni del dispositivo per il quale sono state progettate; la complessità dipende invece dalle funzionalità e dalle tecnologie utilizzate, ad esempio la connessione a database server, lo sfruttamento di socket di comunicazione, l'uso del suono, il collegamento ad altri dispositivi tramite bluetooth, l'acquisizione di immagini da una camera, eccetera. In questo panorama, ciascun produttore di smartphone, PDA e altri “congegni mobili” fornisce generalmente il proprio SDK per lo sviluppo di applicazioni dedicate.

Borland ha strutturato i nuovi ambienti JBuilderX e C++BuilderX rendendoli in grado di supportare i pacchetti SDK forniti da alcuni partner, leader nel mercato mobile.

Jason ha infatti utilizzato l'ambiente C++BuilderX per eseguire una dimostrazione pratica, scrivendo una breve applicazione in linguaggio C++, compilandola ed eseguendola attraverso un emulatore che appare integrato nell'ambiente di sviluppo.

Anche C++BuilderX soddisfa il ciclo ALM permettendo di attraversare le fasi “classiche” di progettazione, sviluppo, test e deploy.

Sebbene C++BuilderX fornisca un'interfaccia uniforme indipendentemente dal dispositivo, lo sviluppo dell'applicazione mobile avviene lavorando con i “runtime” forniti dagli SDK...ma Jason Vokes non ha escluso la possibilità dell'introduzione di un framework con widget che consenta uno sviluppo RAD unificato anche dal punto di vista visuale.

Si possono trovare maggiori informazioni sui prodotti Mobile alla pagina relativa sul sito Borland: http://www.borland.com/mobile.

Conclusioni

Concludo il (faticoso) reportage aggiungendo un giudizio personale sul Delphi Day: attribuisco senz'altro un voto positivo all'evento poiché, nonostante il “taglio” tendenzialmente commerciale (forse inevitabile) di alcune sessioni (d'altronde, si tratta sempre e comunque di informazioni utili), è stato un ottimo espediente per “catturare” alcune nozioni tecniche riguardanti strumenti che già utilizzavo e al tempo stesso conoscerne di nuovi. Inoltre, ho avuto l'occasione di stringere la mano ad alcuni partecipanti del newsgroup pubblico “it.comp.lang.delphi” con cui si intraprendono quotidianamente discussioni tecniche formative e stimolanti. :-)


Marco Breveglieri (marco@abls.it)
ABLS Team Snc – Software & Web
Via De Gasperi, 14 – 42019 Scandiano (RE)

Tel. 0522 981088 – Web: http://www.abls.it – EMail: info@abls.it


Hanno collaborato alla revisione del reportage

Andrea Magni (“Tecnologie D&D”)

Carlo Barazzetta (“InstantObjects”)