Come promesso
nella mia rassegna sui Jolt Awards, presento al popolo di Programmazione.it
Lattix LDM 2.5, il tool che nella categoria
Design Tools And Modeling è stato preferito addirittura a
Borland Together. La base del genio è la semplicità, e questo prodotto usa una semplice ma efficace metodologia, la
DSM (Dependency Structure Matrix or Design Structure Matrix), elaborata al solito
MIT, che riduce la valutazione di un'architettura software ad una semplice ispezione visiva su una
matrice generata automaticamente.
Sostanzialmente, dato in input il codice sorgente, Lattix LDM genera, in automatico e con straordinaria velocità di esecuzione, una matrice che ha sulle righe e sulle colonne tutti i moduli software del progetto; ove un modulo interagisca con un altro, nella cella situata all'incrocio dei due (la convenzione è che il modulo nella colonna usa quello nella riga) viene posto un numero che indica la
forza della dipendenza: di default, rappresenta il numero di dipendenze che una classe ha verso le altre, ma è naturalmente modificabile dall'architetto.
E' immediato verificare alcune proprietà di una matrice del genere: ad esempio, un modulo cui corrisponde una riga (risp. colonna) vuota non è usato (risp. non usa) alcun altro modulo, per cui corrisponde alla radice (risp. all'ultimo strato) della gerarchia. Ugualmente, il prodotto evidenzia quei gruppi di moduli che hanno solo dipendenze
interne, ovvero si usano l'un l'altro; tali gruppi vengono aggregati, sommando i rispettivi pesi, e conservando naturalmente sempre la possibilità di fare un
drill down sui componenti di un medesimo gruppo funzionale. L'intervento (banale) dell'architetto è richiesto solamente per avere, riordinando i moduli ottenuti, una matrice il più possibile simile ad una
triangolare bassa (anche solo a blocchi): in tal caso, evidentemente, avremo una situazione in cui i moduli
in alto usano quelli immediatamente
in basso, ovvero una completa stratificazione dell'architettura.
Inoltre, nel caso in cui non riuscissimo ad avere una matrice triangolare bassa, i numeri posti al di sopra della diagonale principale consentono di identificare immediatamente le dipendenze cicliche. Ancora, l'esame dei pesi permette di identificare moduli
critici per il progetto, assieme ad altre considerazioni: ad esempio, se ad un modulo corrispondono sia una riga che una colonna
piene, questo indica che il modulo usa (ed è usato da) tutti gli altri moduli, per cui è sicuramente di centrale importanza.
E' importante notare, ancora una volta, che l'esperienza dell'architetto ha sempre il suo peso, ma la generazione della matrice e molte analisi su di essa si prestano ad essere automatizzate in larga parte. Ancora, voglio richiamare l'attenzione sul fatto che un gran numero di considerazioni sulla stratificazione dell'architettura e sull'indipendenza/dipendenza funzionale dei singoli moduli può essere espresso sulla base dei
fattori di forma della matrice, che costituiscono un dato
oggettivo, piuttosto che osservando i pesi attribuiti alle interazioni, che possono essere modificati in maniera
soggettiva.
Immaginiamo ora di dover effettuare la stessa analisi sul diagramma UML del software (un significativo esempio è riportato nella documentazione del prodotto): un architetto riuscirebbe ad evidenziare le dipendenze fra i vari moduli solo navigando, certamente non in maniera automatica, il diagramma, utilizzando dunque i colori per evidenziare quelle classi che rappresentano punti di estensione, , moment-interval e via dicendo. Chiunque abbia famigliarità con il linguaggio di modellazione in questione sa che al crescere della complessità del progetto diventa difficile scovare le dipendenze e risolverle, utilizzando unicamente i diagrammi.
La matrice DSM invece
scala magnificamente man mano che le linee di codice si moltiplicano: la dimensione della matrice, ovvero il numero di righe e colonne, aumenta, ma rimane sempre la possibilità di analizzarla
a colpo d'occhio guardandone semplicemente le macrocaratteristiche. Inoltre, indipendentemente dalle dimensioni, la matrice generata da Lattix permette con grande facilità di aggregare macrofunzionalità, piuttosto che, al contrario, di esaminare nel dettaglio i moduli che ci interessano: dal punto di vista pratico, si compattano dei moduli aggregando le rispettive righe e colonne, o viceversa si esplodono i moduli che compongono le macrofunzionalità, con lo stesso meccanismo con cui espandiamo/comprimiamo un albero di cartelle in
Esplora Risorse.
Una caratteristica importante del prodotto è quella di permettere la definizione di regole architetturali. E' possibile ad esempio impedire dipendenze esterne o fra particolari moduli. Tali regole vengono editate, in maniera visuale ed assistita da Lattix, che ha già a questo punto
censito tutte le componenti del software; i moduli che le violano vengono visibilmente evidenziati con un flag rosso. E' altresì particolarmente efficace la rianalisi di una diversa versione di un programma per cui sia già stata generata la DSM, che evidenzia, ove presenti, nuove violazioni delle regole architetturali. Quasi inutile aggiungere che Lattix LDM è in grado di restituire una serie di metriche sul codice, aderenti agli standard di qualità
CMMI e
Six Sigma.
Ho riassunto, sostanzialmente, tutto ciò che l'architetto interessato troverà nel documento
Using Dependency Models to Manage Complex Software Architecture, ove è riportato anche un
case study su un software di significativa complessità, con 200.000 linee di codice. Ancora, la metodologia è illustrata efficacemente
sul sito Lattix; è consigliabile anche seguire la
serie di presentazioni relativa all'uso del prodotto, davvero ben fatte.
Quest'ultimo è disponibile in quattro edizioni, fra cui una di base, la
Community Edition, gratuita previa registrazione, che non permette la definizione di
design rules e la generazione di metriche, ma che continua a mantenere la semplicità di generazione ed analisi della matrice delle dipendenze. Sul sito è riportato
un confronto fra le versioni. E' presente un installer su piattaforma Windows, il quale consente l'analisi di codice Java e Microsoft C/C++ (mi è stata annunciata entro l'estate prossima la disponibilità per .NET), un plugin per Eclipse, ed un archivio compresso per l'installazione su sistemi operativi non Microsoft. La licenza del prodotto, a seconda dell'edizione, varia fra 1000 e 5000 dollari (mi è stato comunicato dalla Lattix, non si tratta di un dato presente sul sito), ma sono applicate politiche di sconto per team di sviluppo che riducono il costo della versione Enterprise fino a 1000 dollari per membro.
L'esempio classico, riportato in tutti i documenti della Lattix, è l'analisi DSM applicata ad
ANT, il maketool basato su Java del progetto Apache. Di default, il prodotto usa come gerarchia iniziale la suddivisione in package di un programma. E' a dir poco istruttivo confrontare la matrice delle dipendenze ottenuta con Lattix con un diagramma UML del tool; naturalmente, è la stessa Casa ad
affermare che, per differenti aspetti dell'analisi, sono necessari sia il
Dependency Model ottenuto con Lattix che il diagramma UML.
Tornando al prodotto in esame ed all'analisi DSM di ANT, notiamo per esempio come il modulo
taskdefs, che dal punto di vista del codice è parte del package
org.apache.tools.ant, in realtà si pone funzionalmente in cima alla gerarchia, come
ant stesso. Fatta questa ristrutturazione, notiamo che i tre package
mail,
tar e
zip non vengono mai usati da
ant, ma solo da
taskdefs: è naturale allora raggrupparli in un sottosistema
util funzionalmente dipendente da
taskdefs stesso. Una nota sull'uso del prodotto: come noto, un package Java può contenere sia classi che package; quando ciò accade, Lattix raggruppa le prime in un sottosistema indicato da un asterisco ("*").
Dopo aver effettuato tutti i cambiamenti necessari all'architettura nella finestra di
ArchMap, se ne può effettuare una review nel tab "Work List" ed assegnare loro un proprietario (ai fini della tracciabilità e della suddivisione del lavoro) ed una priorità. Ovviamente, l'algoritmo di partizionamento DSM può essere applicato ricorsivamente ad ogni sottosistema, facilitando il refactoring del codice, anche in maniera automatica tramite un omonimo pulsante. A questo punto è possibile generare automaticamente un modello concettuale dell'architettura, mostrando opzionalmente (tramite un’apposita voce nel menu
View) il grafo delle dipendenze, che a seconda dei casi può dare maggiore informazione, così come complicare l'analisi.
Un'interessante iniziativa di carattere commerciale è la disponibilità degli ingegneri Lattix ad effettuare una prima valutazione sul progetto del cliente. Attraverso
un apposito form il cliente contatta la Lattix sottoponendo un'applicazione per l'analisi preliminare; questa viene di solito svolta nel giro di ore, e discussa con il cliente in una sessione Web privata. L'analisi è gratuita e senza impegno di acquisto, tranne ovviamente nel caso in cui il cliente voglia approfondirla; nel qual caso, acquista dalla Casa un pacchetto di servizi.
L'installazione del prodotto è quantomai semplice, almeno nella versione Enterprise da me provata, e viene installato automaticamente anche il plug-in per Eclipse. Il prodotto consente di essere immediatamente produttivi, scegliendo semplicemente da
File | Open il jar di codice da analizzare. A titolo di prova ho analizzato sia il codice sorgente di
AXIS presente fra i plugin di Eclipse che i package per la reportistica di un interessante progetto di plugin di Eclipse per la Business Intelligence,
BIRT, ed in entrambi i casi l'analisi utilizzando un Pentium Mobile ed 1 Gb di RAM è stata velocissima. Da notare che il prodotto consente di tenere aperti più progetti contemporaneamente.
Come si suol dire, l'appetito vien mangiando, ed a questo punto mi è venuta l'idea di fare un po' le pulci al lavoro degli sviluppatori dell'ultima versione di
Tomcat. In verità, non posso che complimentarmi con loro: nessun problema rilevato esaminando la Servlet o la JSP API, e dando un'occhiata per esempio alla Naming Factory, troverete che le classi Factory utilizzate hanno addirittura una matrice associata vuota, il che significa che non è presente alcuna dipendenza interna fra i package che le compongono: un perfetto esempio di sviluppo per componenti! Ancora, correttamente, nessuna delle classi helper usa quelle specifiche del package. Rileverete inoltre che alcune classi, come le due MailFactory, sono autoconsistenti, ovvero non usano altre classi del jar.
Naturalmente, la cosa più interessante è poter applicare l'analisi DSM all'intero Tomcat, evidenziando le dipendenze tra i vari package: questo è possibile grazie al wizard incluso nel comando
File | New Project. Apriamo un nuovo progetto
Tomcat, di tipo Java, selezionamo la checkbox
JAR files, e navighiamo fino alla cartella che contiene il progetto: verranno automaticamente rilevati ed inclusi tutti i JAR che compongono il popolare servlet engine. Clicchiamo su
Finish (un piccolo bug: risulta ancora cliccabile la voce
Next) e verrà effettuata in automatico l'analisi dell'intero progetto. Dalla voce di menu
File | Report è possibile generare un report in Excel per il progetto, con differenti fogli di lavoro utilissimi per la documentazione: matrice DSM, regole architetturali, violazioni alle regole stesse e dipendenze esterne. Anche questa è una caratteristica che mi ha entusiasmato.
Il plugin per Eclipse è altrettanto semplice da utilizzare: si carica il package da analizzare in Eclipse, e dal
Package Explorer (il menu ad albero sulla sinistra) ci si clicca sopra col tasto destro del mouse; nella nuova voce
Lattix occorre scegliere
Show Lattix Dependency Model. Alla prima esecuzione occorrerà invece scegliere la voce
License ed inserire i dati ricevuti all'acquisto. Nella parte destra della GUI di Eclipse, proprio sotto i tre classici pulsanti di ridimensionamento, troverete due pulsanti
Lattix e
Java che consentono di passare dall'interfaccia di Lattix a quella di Eclipse.
Un po' più complicata è la procedura per poter effettuare l'analisi di codice Microsoft C/C++ (naturalmente dal solo prodotto standalone), che apprendiamo dall'ottima guida in linea, una vera miniera di informazioni anche per quanto riguarda la personalizzazione dell'analisi. Lattix usa i file
BSC generati da Visual Studio, che contengono i riferimenti fra simboli e che necessitano dell'apposito
Browser Toolkit, per generare il Dependency Model iniziale; una volta che il file .ldm è stato generato, l'analisi prosegue come nel caso normale. Occorre allora
scaricare il Browser Toolkit appropriato per la versione di Visual Studio che si sta utilizzando, installarlo, e copiare il file
kit/bscsdk/bin/msbsc70.dll (nel caso stiate utilizzando Visual C++ .NET) nella cartella
bin dell'installazione di Lattix. L'help in linea fornisce anche istruzioni molto dettagliate su come generare il file BSC per un progetto.
Ho cominciato le mie prove col linguaggio di Stroustrup con un semplice programma di steganografia
scaricato dall'inesauribile Code Project. L'analisi è in questo caso leggermente complicata da diversi fattori: le ovvie dipendenze fra le classi ed i relativi file di header; il ruolo del file stdafx.cpp che, naturalmente, presenterà sia la relativa riga che la colonna vuote (si prevede, per le future versioni di Lattix, un'opzione che lo escluda dalla matrice); e, forse più importante, il fatto che in C++ non vale l'associazione presente in Java fra nome della classe e nome del file, per cui l'analisi sulle dipendenze fra file sorgenti non corrisponde automaticamente ad un'analisi sulle dipendenze fra classi. Ad esempio, una semplice analisi sulla matrice generata per il progetto
CHTML Viewer, un interessante parser HTML, porterebbe a concludere che sussistono delle pericolose dipendenze cicliche e che, addirittura, main.cpp è usato da molti dei file del programma; in realtà, quel che succede è che, nelle applicazioni MFC o ATL, l'oggetto root presente in main.cpp viene referenziato da altre parti del programma. Per finire, potreste scaricare dal sito della Lattix una
versione dotata di BSC di Apache 2.0.51 e seguire l'esempio illustrato nell'Help del tool.
In conclusione, per facilità d'uso ed aiuto all'analisi, sono a dir poco entusiasta di Lattix LDM. Naturalmente attendo con impazienza la disponibilità della versione per codice .NET; nel frattempo, spero che questa review contribuisca, nel suo piccolo, a portare sul desktop degli architetti questo immeritatamente ancora poco conosciuto prodotto.