Inizia da questo numero una miniserie di articoli su un argomento non prettamente tecnico: le competenze e la formazione degli sviluppatori. Un argomento con una duplice udienza: in primis, i programmatori novizi, gli appassionati o semplici hobbisti che sono agli inizi della programmazione; in secondo luogo, i manager, dirigenti o comunque decision maker che si trovano davanti il compito si fare staffing per il proprio progetto.
Ipotizziamo che siate dei programmatori novizi che si avvicinano per la prima volta al mondo della programmazione. Avete scelto Java, ed avete trovato questa grande risorsa online che è MokaByte. E ora? È probabile che abbiate scelto l‘articolo che tratta l‘argomento più interessante e che lo stiate leggendo, cercando di capirne gli esempi. Può anche darsi che, non avendo esperienza di programmazione, abbiate acquistato un libro, come ad esempio Guida pratica di Java, Seconda Edizione. Questo è un classico modo di agire degli autodidatti.
Altre persone preferiscono iniziare con un corso, magari sotto forma di aiuto da parte di un amico, oppure in forma più professionale, come quelli offerti da MokaByte stessa. In questo caso dovete sforzarvi meno, perché c‘è una persona che vi spiega le cose e cerca di farvele capire seguendovi da vicino.
Una montagna da scalare
Ad ogni modo, in qualunque maniera abbiate iniziato, una cosa è certa: avete davanti una alta montagna da scalare. Alcune cose possono sembrare più semplici, e altre più complicate. All‘inizio è normale sentirsi spaventati, e per una buona ragione. Diventare sviluppatori Java, anche senza diventare veri e propri Guru, è una impresa difficile, che richiede tempo, studio e impegno per raggiungere un livello da “cintura nera”. perché cintura nera? È una similitudine con le arti marziali orientali, dove i principianti studiano per un certo numero di anni, che in funzione delle diverse discipline può andare per esempio, dai cinque ai sette anni. Dopo di che possono pensare di diventare cintura nera. Questo stato non significa che lo studente si può considerare arrivato. Piuttosto, significa che ha raggiunto un livello di base che gli permette di essere un iniziato in una determinata disciplina. Automaticamente, non significa diventare invincibili o “saggi” o “maestri” che non hanno più bisogno di istruzione. La cintura nera è solo il punto di partenza.
Nella programmazione il meccanismo è simile: si inizia senza sapere nulla, poi dopo anni di esperienza, il cui numero può variare in funzione della complessità dell‘ambiente in cui si opera, si raggiunge un livello di competenza senior (per semplicità ora chiamiamolo così) e da qui si inizia la propria crescita.
D‘altra parte, come già esposto in [1], la realizzazione di software può essere considerata in tre modi diversi: come ingegneria, come arte o architettura. Arte: ecco il punto di congiunzione con il concetto del lungo apprendistato prima indicato.
I sette pilastri della saggezza
Ma perché è così complicato e lungo imparare a programmare in Java? Semplicemente, perché ottenere una buona padronanza di una disciplina richiede tempo e sforzo. Non è quindi un problema specifico di Java, ma è qualcosa di comune. In ambito informatico, la conoscenza della piattaforma Java non richiede significativamente più o meno impegno rispetto ad alternative come la piattaforma .NET, Win32 o POSIX. Anche perché alla base c‘è la conoscenza dei concetti basilari dell‘informatica, come i thread e i processi, le strutture dati e gli algoritmi, la logica procedurale e a oggetti.
È chiaro che poi ogni piattaforma ha le sue peculiarità . Ad esempio, secondo il modesto parere di chi scrive, il linguaggio Java ed alcuni elementi di base della piattaforma sono più semplici dei corrispettivi .NET. Ad esempio, classi parziali e le strutture presenti nella piattaforma di Microsoft sembrano una complicazione tutto sommato non così utile. Ma alla fine può essere solo una questione di gusti: c‘è chi da una maggiore importanza alla semplicità e chi invece preferisce più complessità e funzionalità .
Dopo qualche anno di esperienza nello sviluppo con la piattaforma Java mi sento di indicare come indispensabili, per uno sviluppo corretto in Java, questi sette argomenti:
1. OOP (Object Oriented Programming).
2. Le basi di Java.
3. Strutture dati e algoritmi.
4. Eccezioni.
5. Design Pattern.
6. Refactoring.
7. Open Source.
Vediamoli in dettaglio.
OOP
La conoscenza dei concetti della programmazione orientata agli oggetti è indispensabile per realizzare codice Java in quanto, se si disponesse solo delle conoscenze legate alla programmazione procedurale, si produrrebbe codice di bassa qualità che potrebbe avere una serie di problemi:
- avendo utilizzato un linguaggio ad oggetti per scrivere codice procedurale, il software presenterebbe una certa impedenza con la libreria di base e le librerie di terze parte, rendendone più complessa l‘integrazione.
- Spesso scrivere codice procedurale porta alla realizzazione di classi con metodi statici. Questo fatto riduce la possibilità di riutilizzare il codice tramite l‘ereditarietà , aumentando i vincoli tra le classi.
- Il software eredita tutti i limiti della programmazione procedurale, che la OOP è nata per risolvere.
È dunque indispensabile maturare una familiarità con concetti come incapsulamento, ereditarietà , tipi, polimorfismo, ridefinizione, overloading. Pensare ad oggetti è radicalmente diverso dal pensare strutturato, quindi chi viene da una esperienza con il secondo avrà sicuramente dei problemi di comprensione, ma è importante non accontentarsi di ottenere l‘obbiettivo prefissato, ma di farlo nel modo “più a oggetti” possibile. Forse le prime volte non si riuscirà completamente nell‘intento, ma sicuramente la volta dopo sarà meglio. L‘importante è continuare a migliorarsi.
Le basi di Java
La sintassi del linguaggio è tutto sommato semplice, con le sue istruzioni di controllo del flusso strettamente ereditate dal linguaggio C. Vista la diffusione di questo linguaggio, molti sviluppatori si trovano subito a proprio agio, anche perché molti altri linguaggi hanno costrutti simili e sintassi quasi identica (Basic, Ruby, Perl, Bash, PHP). Ma le basi del linguaggio non sono solo queste. Ad esempio, bisogna conoscere i metodi della classe Object come hashCode(), equals() o clone(). Molti programmatori alle prime armi non li approfondiscono in quanto non sono indispensabili per iniziare a programmare. Ma quando si comincia a creare i propri tipi di dati, e soprattutto si inizia ad utilizzarli insieme alle strutture dati, è necessario sapere come funzionano.
È importante anche sapere come funziona l‘allocazione dinamica della memoria ed il Garbage Collector. Diversamente si può realizzare codice che funziona, ma che non è efficiente. Il che vuol dire che il proprio software va bene a livello di hobby, ma non potrà mai essere utilizzato in produzione in sistemi di una certa dimensione.
Un altro aspetto da approfondire è la gestione delle stringhe ed i relativi concetti di immutabilità e pooling. Anche questa parte del linguaggio può essere fonte di inefficienze.
Strutture dati e algoritmi
Prima dell‘avvento delle tecnologie a oggetti le strutture dati rivestivano una importanza fondamentale nei programmi, in quanto costituivano il modo preferenziale per memorizzare le informazioni [2]. Strutture come liste linkate, liste doppiamente linkate, hashmap, stack, pile, code, dizionari, buffer circolari sono ancora importanti, perché il loro corretto impiego permette un uso efficiente delle risorse del computer. Dettagli importanti sono il costo di inserimento, ricerca e cancellazione delle liste linkate, oppure la struttura interna di un HashMap. È importante anche sapere come implementare le proprie classi in modo che possano essere ospitate correttamente ed in modo efficiente nelle strutture dati fornite dal linguaggio Java.
Eccezioni
Un altro capitolo spesso sottovalutato nella realizzazione di software in Java è la gestione delle eccezioni. È un argomento difficile: è necessaria una certa esperienza per capirne bene il funzionamento. Per prima cosa è necessario notare che in Java ci sono tre tipologie di “eventi eccezionali”: le eccezioni controllate, quelle non controllate e gli errori. Se l‘ultima tipologia designa eventi che, se accadono, poco ci può fare il programmatore (esaurimento della memoria, errori interni, formati di file .class sbagliati), le eccezioni sono invece un argomento che siamo obbligati ad affrontare, in quanto tutta la libreria di base del linguaggio ne fa ampio uso.
Una soluzione che si utilizza spesso per gestirle è… ignorarle. In casi migliori vengono scritte su file di log, oppure propagate. Altre volte vengono ignorate le specificità e si utilizza solo l‘eccezione generica: Exception.
In parole povere, del codice Java di buona qualità deve fare un uso accorto delle eccezioni, che sia conforme con le specifiche di SUN, con l‘utilizzo di prassi presente negli altri componenti software interfacciati, che sia esplicativo ed efficiente.
Design Pattern
Una volta consolidate le basi del linguaggio e della piattaforma è possibile passare allo sviluppo del proprio software. Dopo i primi esperimenti si noterà che alcune problematiche si ripetono. E ci si chiede: avrò implementato la soluzione più efficiente? Può essere di si. Ma il segreto qui non è quello di scervellarsi alla ricerca della propria soluzione originale. Molto probabilmente, lo stesso problema che state affrontando lo ha incontrato qualcuno prima di voi. Conviene dunque controllare nei diversi cataloghi di Design Pattern se esiste già una soluzione al vostro problema. Un Design Pattern è infatti una soluzione comprovata ad un problema ricorrente.
La non conoscenza dei Design Pattern principali [3] [4] comporta infatti molto spesso la ripetizione degli stessi errori del passato.
È un po‘ come studiare la storia: si dice che conoscerla è un modo per non ripeterla.
Per i Design Pattern il discorso è simile, anche se è un catalogo di buone soluzioni, invece che di errori.
Man mano che il sistema software che state progettando cresce di dimensione, l‘uso dei Design Pattern diventa sempre più indispensabile. Purtroppo, per acquisire familiarità con i pattern è necessaria molta pratica e tempo. Alcuni libri sono infatti un condensato di nozioni: è indispensabile del tempo per digerirli e per metterli in pratica. Solo applicandoli, infatti, si matura l‘esperienza necessaria per renderli parte di noi.
Refactoring
Gli argomenti esposti fino a qui ci hanno portato a raccogliere le competenze necessarie alla realizzazione di software complessi. Ma, al crescere della complessità del software, crescono anche i vincoli tra le sue diverse componenti. Le classi sono sempre più intrecciate tra di loro, i sottosistemi più correlati, ed una modifica, anche solo alla firma di un metodo, diventa un affare complesso. Quindi si tende a tirare avanti, ignorando una correzione, ben sapendo che sarebbe invece necessario farla, per evitare di dover mettere mani a molte parti del codice.
Strumenti di sviluppo moderni, come per esempio Eclipse, sono dotati di strumenti per intervenire sul codice in modo automatico. Ad esempio, si può rinominare un metodo cambiando in automatico tutti i riferimenti ad esso. E la modifica avviene a livello semantico, e non con una semplice ricerca testuale. Ad esempio, se lo stesso nome viene utilizzato per un attributo, questo non viene cambiato.
Altre modifiche automatiche permettono di muovere una classe da un package all‘altro, cambiare la firma di un metodo, estrarre una classe interna per crearne una top-level, fare l‘inline di metodi. Tutte queste cose, prima di entrare a far parte di un IDE sono stati studiati come interventi manuali, legati al concetto di Unit Testing e prendono il nome di Refactoring [5]. È bene esserne a conoscenza, in quanto questa competenza libera da codice mal progettato: lo si può migliorare senza cambiarne la logica di funzionamento, utilizzando strumenti automatici e procedure che assicurano che non venga “rotto niente”.
Open Source
L‘ultimo argomento non è relativo alla programmazione. Piuttosto ha a che fare con il “non fare”. Internet è piena di siti zeppi di librerie e framework Open Source [6] (p.e. jakarta.apache.org, codehaus.org, sourceforge.net e altri). Spesso le licenze con cui vengono distribuiti questi software, anche in sorgenti, consentono un largo uso all‘interno delle proprie applicazioni, anche di tipo commerciale.
Quindi, dopo aver speso anni per imparare numerosi concetti, nozioni e competenze, alla fine in molti casi quale strada si prende? Si scarica un componente Open Source e lo si integra nella propria applicazione. Sembra un paradosso, ma non è così, per molte buone ragioni. Per esempio, integrare componenti esistenti consente un significativo risparmio di tempo. Inoltre spesso questi componenti sono ben testati e documentati. C‘è una regola, in questo campo: “se esiste, compralo” (in realtà si diceva ai tempi di Visual Basic, dove i componenti aggiuntivi erano a pagamento, ma la frase rende comunque bene l‘idea).
Conclusioni
La chiave per diventare un buon programmatore è la conoscenza. Java è un mondo vasto, è quindi necessario avere pazienza e dedicare il tempo necessario al suo studio. Sono stati suggeriti sette argomenti, molto ampi, che sono i punti chiave per maturare una significativa competenza nel mondo Java. Uno sviluppatore completo deve avere una buona esperienza in tutti questi campi per poter programmare in modo armonico ed efficiente.
Riferimenti bibliografici
[1] Gilbert-McCarty, “Object Oriented Programming”, Waite Group Press, 1998
[2] Niklaus Wirth, “Algoritmi + Strutture dati = Programmi”, Prentice Hall, 1976
[3] Gamma, et al., “Design Patterns”, Addison-Wesley, 1995
[4] M. Bigatti, “UML e Design Pattern”, Hoepli, (in uscita a luglio 2006)
[5] Martin Fowler, “Refactoring”
[6] M. Bigatti, “Java e Open Source”, Tecniche Nuove, 2005
Massimiliano Bigatti è sviluppatore senior, autore tecnico e appassionato di fotografia.
Certificato, tra le altre, come SUN Certified Enterprise Architect for Java2 Enterprise
Edition Technology, lavora presso un importante business solution provider.
Nel tempo libero scrive per diverse riviste di informatica e ha scritto una decina di libri,
quasi tutti su Java, tra cui "Java e Open Source", Tecniche Nuove 2005.
Il suo sito personale è raggiungibile all‘indirizzo www.bigatti.it.