MokaByte
Numero 33 - Settembre 99
|
||||
|
|
strumenti e tecniche
|
||
|
Antonio Cisternino |
alcune tecniche per sviluppare codice riutilizzabile e per gestire grossi progetti in Java |
||
|
||||
Sono molte le novità che Java ha introdotto nel mondo della programmazione. Sicuramente tra le più importanti troviamo l’imposizione di alcuni standard di codifica e l’esistenza di un tool standard di documentazione automatica. In questo articolo e nel prossimo illustrerò come sfruttare queste caratteristiche del linguaggio per organizzare il proprio codice in modo tale che sia riutilizzabile. Le tecniche che descriverò saranno altrettanto utili per gestire progetti di grandi dimensioni.In questa prima puntata descriverò innanzitutto gli strumenti disponibili per amministrare il proprio codice e successivamente come questi possano essere sfruttati per trarre dei notevoli vantaggi nello sviluppo. La seconda puntata sarà invece dedicata allo sviluppo di una piccola libreria che faccia uso degli strumenti illustrati. |
||
IntroduzioneSono molte le novità che Java ha introdotto nel mondo della programmazione. Sicuramente tra le più importanti troviamo l’imposizione di alcuni standard di codifica e l’esistenza di un tool standard di documentazione automatica. In questo articolo e nel prossimo illustrerò come sfruttare queste caratteristiche del linguaggio per organizzare il proprio codice in modo tale che sia riutilizzabile. Le tecniche che descriverò saranno altrettanto utili per gestire progetti di grandi dimensioni.In questa prima puntata descriverò innanzitutto gli strumenti disponibili per amministrare il proprio codice e successivamente come questi possano essere sfruttati per trarre dei notevoli vantaggi nello sviluppo. La seconda puntata sarà invece dedicata allo sviluppo di una piccola libreria che faccia uso degli strumenti illustrati.Gli strumenti offerti dal JDK e dal linguaggioIniziamo questa panoramica dagli strumenti offerti dal JDK di Sun. Ho scelto di illustrare le tecniche utilizzando il semplice JDK perché è un tool gratuito. Molte delle considerazioni che farò possono comunque essere utilizzate anche in ambienti di sviluppo che, tra l’altro, spesso si appoggiano al JDK.I tre comandi principali per sviluppare librerie in Java sono: javac, javap e javadoc. Oltre a questi comandi forniti col JDK è possibile utilizzare script di sistema per automatizzare alcuni aspetti della generazione della documentazione e del bytecode.Il javac è il compilatore vero e proprio e consente di compilare le classi contenuti nei file con estensione .java. Questo strumento condiziona già l’organizzazione del proprio codice poiché impone che ogni file contenga al più una classe dichiarata public e che il nome del file coincida col nome di tale classe. Come tutti gli strumenti a riga di comando supporta vari switches che consentono di controllarne il comportamento. In particolare lo switch –d consente di controllare la destinazione dei file .class prodotti dal compilatore.Il comando javadoc consente di produrre la documentazione del proprio codice a partire da commenti speciali inseriti nel sorgente. Il risultato dell’uso di questo strumento è un insieme di pagine HTML che contengono la documentazione. Chi è familiare con la documentazione prodotta da Sun per il JDK ha quotidianamente un esempio di documentazione generata da javadoc.Java e il meccanismo dei packageUna volta introdotti gli strumenti fondamentali consideriamo un meccanismo fondamentale offerto da Java per la produzione di librerie: i package. Col concetto di package Java consente di scrivere codice modulare, contenuto in più file, svincolando però la classe dal file che la contiene. In pratica il sistema Java conosce tutte le classi disponibili poiché contenute in una o più directory del filesystem specificate nella variabile d’ambiente CLASSPATH.Un programma Java è costituito da un insieme di classi. Esse sono a loro volta partizionate in vari package. Un package è quindi un insieme di classi e altri package, ai quali è associato un nome. Un esempio di classi suddivise in package è dato dalla libreria standard di Java.Il nome completo di una classe è costituito dal nome dei package in cui è contenuta separati dal punto; il meccanismo offerto dal costrutto import consente di evitare di specificare il nome esteso di una classe ogni volta che serve.E’ sempre possibile creare nuovi package semplicemente cominciando il proprio file contente il codice Java con il costruttopackage it.infomedia;
Per costruire un proprio package ci sono due strategie possibili: creare l’albero delle directory e scrivere i sorgenti localizzandoli nel posto opportuno, usare lo switch del compilatore –d. Nel primo caso semplicemente si crea una directory per ogni package (eventualmente annidando le directory) e si crea in ogni directory i file .java relativi al package associato. Sempre seguendo l’esempio in della figura 1 il sorgente DevClass.java contenente la classe DevClass si deve trovare nella directory infomedia. In questo caso per compilare i file di un package è sufficiente un semplice javac *.java
eseguito nella directory infomedia. Nel secondo caso invece i sorgenti si mettono in una cartella qualsiasi (che può contenere sorgenti di package differenti, anche se è sconsigliabile dal punto di vista organizzativo) e si esegue il comando javac –d outdir *.java dove outdir
è la directory dove verranno messi i file risultato della
compilazione. Il javac inoltre si occupa di creare l’albero delle
directory necessario (nella directory outdir) e di depositare i
file .class nelle posizioni opportune.Il vantaggio nel secondo approccio
è evidente: permette di separare i sorgenti dal codice eseguibile
ottenendo una buona organizzazione del proprio codice. Se si sfrutta la
naturale gerarchia dei package è possibile racchiudere tutto
il proprio codice sotto un enorme package facilitando, come vedremo
in seguito, il riuso del codice.
I meccanismi di protezioneI meccanismi di protezione offerti dal linguaggio, mediante l’uso delle keywordpublic, private e protected, consentono di controllare il proprio codice e di definire delle librerie che siano realmente riutilizzabili e facilmente estensibili.Descrivo brevemente il significato di queste parole chiave del linguaggio per rinfrescare le idee a chi non le usa frequentemente. I meccanismi di protezione sono stati introdotti nei linguaggi orientati agli oggetti per permettere un riuso controllato del codice. Il controllo da parte del compilatore dei diritti sui singoli membri di una classe consente, ad esempio, di evitare che una classe utilizzata internamente nella libreria venga usata impropriamente al suo esterno. I modificatori di accesso permettono un maggiore incapsulamento dei dati all’interno della classe impedendo di accedere alle variabili membro della classe se non tramite metodi che ne alterino il valore.La parola chiave public identifica quei membri di una classe che sono accessibili da chiunque. La parola chiave protected identifica quei membri che possono essere acceduti solo nella definizione dei metodi delle classi derivate dalla classe che dichiara il membro protected. La parola chiave private identifica invece i membri che possono essere acceduti solo all’interno della classe stessa. In Java, se non si specifica altrimenti, ogni membro è accessibile solo dalla classe che lo contiene e dalle classi che sono nello stesso package. Questo può essere molto utile per condividere variabili tra classi diverse di uno stesso package senza che queste siano accessibili all’esterno del package stesso.Javadoc: documentare automaticamente il proprio codiceIl sistema di generazione automatica del proprio codice è forse la più grande novità offerta da Java come supporto alla codifica di sistemi complessi e librerie. In questo paragrafo descriverò, in maniera compatta, l’uso del tool javadoc per documentare il proprio codice. Successivamente considereremo come questo strumento, unito ai precedenti possa fare miracoli nel riutilizzo del codice. l tool javadoc prevede che il codice sia commentato con dei commenti speciali compresi tra /** e */. Ovviamente questi commenti sono un caso particolari dei commenti previsti per il linguaggio e quindi non sono identificati dal compilatore. Sono inoltre previste delle direttive particolari per informare il sistema di documentazione sul significato dei commenti; queste direttive cominciano col carattere @.I commenti javadoc solitamente precedono una classe, oppure uno dei membri della classe; il sistema considera un commento associato al membro che segue immediatamente nel sorgente e lo usa per generare la documentazione relativa ad esso. In questo modo è possibile associare un commento ad ogni membro di una classe e alla classe stessa. I commenti sono espressi in HTML e possono quindi contenere tabelle e ogni sorta di tag HTML (persino delle applet).Per capire meglio come funziona il sistema supponiamo di voler commentare la seguente classeclass foo {Un possibile modo per commentare la classe è riportato nel seguente listato **
Come usare gli strumenti descritti?Siamo finalmente giunti al momento in cui posso descrivere come utilizzare gli strumenti finora descritti per realizzare librerie e codice realmente riutilizzabile.Di seguito descriverò alcune tecniche (forse è meglio chiamarle considerazioni utili) di base. Nella prossima puntata mi concentrerò invece su feature avanzate come la gestione delle risorse in una libreria, l’internazionalizzazione, l’uso dei file jar e la personalizzazione della documentazione come strumenti di livello più elevato che consentono lo sviluppo di librerie ancora più versatili. Non voglio entrare nei dettagli metodologici che si nascondono dietro la strutturazione del codice di un grosso progetto o di una libreria poiché sarebbe argomento troppo spinoso e complesso per essere affrontato in un articolo. Piuttosto vorrei soffermarmi a riflettere cosa possono fare questi strumenti per aiutare a strutturare e mantenere il proprio codice. Una delle principali novità introdotte con Java e legate al meccanismo dei package è che non esiste più il concetto di file eseguibile bensì l’insieme di classi Java compilate e suddivise in package. Grazie al meccanismo gerarchico dei package è possibile raccogliere tutto il proprio codice sono un grosso package che poi si differenzia prima per progetto, poi per modulo e per funzionalità. Sun suggerisce di usare il meccanismo gerarchico tipico delle URL al contrario. Il codice sviluppato nell’ambito di Dev, ad esempio, potrebbe trovarsi nei package che hanno come prefisso it.infomedia.dev. Strutturare il proprio lavoro in package risulta quindi una scelta vincente dal punto di vista del riuso del codice poiché nell’ambiente Java sarà sempre disponibile tutto il proprio lavoro. Ovviamente è importante individuare come suddividere le proprie classi per far sì che sia sempre possibile individuare il numero di package adeguato per non regalare più di quanto promesso ad un committente.Una strategia che spesso io uso per organizzare il mio personale albero di codice Java è quello di creare un package per ogni progetto, se necessario spezzare ulteriormente il package in sotto-package. Se durante lo sviluppo ci si accorge che si stanno sviluppando classi che potrebbero essere utili in futuro si devono adottare due accorgimenti: creare un package (o spostare la classe in un package già esistente) dove mettere la classe con quelle che immediatamente o in futuro saranno correlate; cercare di meditare con attenzione sulle interfacce e sui controllo di accesso alla classe per garantire la massima riusabilità.In Figura 2 è riportato un esempio di albero di package che ho adottato nello sviluppo del sistema CompAss presso l’Università di Pisa.
Come si può
notare il package compass è affiancato da molti package
che sono stati sviluppati nell’ambito di questo progetto ma che ho successivamente
riutilizzato. Esempi di questo tipo di package sono il package
vserver che incapsula un server TCP concorrente e il package jcx
che contiene un certo numero di componenti grafici che possono essere riutilizzati
in altri progetti. Osservate infine come tutto l’albero dei package
sia sotto it.unipi.di che è il prefisso dei package sviluppati
presso il dipartimento di Informatica dell’Università di Pisa.La
documentazione del proprio codice è sicuramente fondamentale per
la manutenzione del codice. Sviluppando con Java ho imparato certamente
una cosa: l’uso di javadoc è essenziale per mantenere la
sincronia tra ciò che fa il codice e ciò che è scritto
nella documentazione. Per fare un esempio non banale, il già citato
sistema CompAss fa uso di un certo numero di linguaggi per cui è
stato necessario specificare la sintassi. L’unica ragione per cui la sintassi
implementata è coerente con quella nella dichiarazione è
proprio che ho potuto aggiornare la documentazione direttamente nel sorgente
ad ogni modifica. Inoltre tutte le librerie sviluppate, essendo ben documentate,
sono state riutilizzate in altri progetti, anche non da me che le avevo
sviluppate.
ConclusioniIn questo articolo ho presentato gli strumenti di base che Java offre per gestire il proprio codice. Nella prossima puntata invertirò le parti e mi concentrerò sullo sviluppo di librerie introducendo occasionalmente feature avanzate quando necessario. Svilupperò inoltre una piccola libreria come esempio pratico di applicazione delle tecniche descritte. |
|
||
|
||
MokaByte ricerca
nuovi collaboratori
|
||
|