Home   |   Archivio   |   Chi siamo   |   Contatti
Giancarlo Crocetti
Project Management
III parte - Development Phase
di
Giancarlo Crocetti
È arrivato il momento di implementare il sistema descritto nel DDD (Detailed Design Document). Vedremo come l'uso di UML sia di grandissimo aiuto in questa fase, semplificando molti aspetti implementativi. Se siamo riusciti a costruire un buon POC (Proof Of Concept) ed un buon DDD, allora la fase implementativa sarà semplicemente un esercizio di programmazione che verrà attuata senza particolari difficoltà.

Come al solito rispondo subito alla domanda: Dove cominciamo?

Vi ricordo che nel POC e DDD sono contenute tutte le informazioni di cui avete bisogno: nel POC troverete tutto ciò che il sistema deve essere in grado di fare (specifica funzionale e use cases), mentre nel DDD troverete le informazioni su come il sistema risolve ogni particolare funzionalità e l'ambiente in cui dovrà essere implementato.

Il primo passo spetta al project management che, insieme al team leader, assegna ad ogni componente del team il rispettivo task.

Nello sviluppo OO, molto spesso, questa fase di assegnazione, si riduce, banalmente, nell'elencare la lista di componenti da sviluppare ed assegnarli agli sviluppatori: il mio consiglio è quello di prestare molta più attenzione a questo piccolo, ma importante, dettaglio.

Un errore comune è quello di dimenticare che i componenti da sviluppare hanno un certo grado di dipendenza gli uni con gli altri (la cui complessità dipende dall'applicazione da costruire) e questo si traduce nell'impossibilità di lavorare ad un componente senza aver completato prima il componente da cui questo dipende. Ad esempio: se la classe Mammifero estende la classe Animale, Mammifero deve essere implementata dopo Animale. Se ora assegno la classe Mammifero a Claudio e quella di Animale a Giuseppe, ed entrambi hanno due giorni di tempo per la loro implementazione, Claudio si troverà in enorme difficoltà lavorando senza la classe Animale.

Il primo passo è, quindi, quello di evidenziare tutte le dipendenze tra le componenti da sviluppare, e questo è estremamente facile se nel design è presente un buon diagramma delle classi. Il caso descritto nell'esempio precedente può, quindi, essere risolto in due modi:

1. Assegnare lo sviluppo delle classi Animale e Mammifero a Claudio oppure a Giuseppe. 2. Assegnare la classe Animale a Giuseppe e quella di Mammifero a Claudio, ma evidenziare nel Project Plan che lo sviluppo di Mammifero inizierà dopo quello del componente Animale.

Per quanto riguarda l'assegnazione dei task, se il team di programmatori ha dato un forte contributo durante la fase di design, può accadere che siano gli stessi programmatori a scegliere quali parti del sistema sviluppare, e se questo non crea grandi problemi per qualche ragione particolare, io consiglio vivamente di intraprendere questa strada. Non c'è cosa migliore che vedere l'entusiasmo nella fase iniziale di implementazione.

A questo punto abbiamo assegnato ad ogni sviluppatore il proprio compito e creato uno piano di sviluppo dettagliato con le varie scadenze da rispettare: la fase di implementazione è ufficialmente iniziata.

Il project manager dovrebbe a questo punto mantenere un costante contatto con il gruppo di lavoro e stabilire un meeting a settimana (ma questo dipende della complessità del progetto) allo scopo di verificare l'andamento della fase implementativa ("Status Meeting"). Per qualsiasi altra comunicazione o richiesta, il project manager comunicherà direttamente con il Team Leader.

A seconda dell'azienda, il team leader può partecipare al progetto anche in veste di sviluppatore, oppure operare esclusivamente come responsabile dello sviluppo ed aiutare il team di programmatori in caso di problemi tecnici o suggerimenti. Nella maggior parte dei casi il team leader partecipa attivamente al progetto anche come sviluppatore, ma questa è una pura scelta aziendale che non pone nessuna pregiudiziale sulla buona riuscita del progetto.

Vorrei a questo punto descrivere un esempio di buon ambiente di sviluppo e alcune tecniche di testing che hanno lo scopo di ridurre dipendenze ed aumentare la qualità del software prodotta.

Figura 1 - Ambiente di Sviluppo
Figura 1 - Ambiente di Sviluppo

Ci sono diversi ambienti da configurare all'inizio della fase implementativa, ed anche se questo è più un lavoro da system administrator, voglio lo stesso menzionarla perché la considero parte integrante del progetto. L'ambiente di sviluppo e gli strumenti utilizzati dovrebbero essere stati descritti in dettaglio nel DDD:

Development Environment: Questo ambiente è l'ombrello che deve mimare esattamente l'ambiente di produzione. Deve contenere esattamente lo stesso software (e la stessa versione) di quello utilizzato per la produzione. Inoltre deve essere completamente accessibile agli sviluppatori. Questo significa avere:

  • Source Control Software utilizzato come archivio centrale del codice sviluppato ed eventualmente per l'etichettamento delle varie release. Esempi di Source Control Software sono: PVCS, Visual SourceSafe, CVS, TestTrack Pro, ecc.
  • Database, configurato con la userId e password per gli sviluppatori.
  • Application Server, per il deployment del codice creato.
  • Accesso al computer di development attraverso network
  • Se si tratta di un'applicazione Web il web server configurato esattamente come nell'ambiente di produzione con tutti i certificati SSL necessari.
  • Ogni altro software necessario come descritto nel DDD.

Local PCs: parto dal presupposto che tutti i programmatori abbiano installato sui loro PC tutto il software necessario allo sviluppo e questo include:

  • Ambiente IDE per la scrittura ed il testing del codice: è preferibile avere per tutti lo stesso software e la stessa versione. Molto importante è la compatibilità del software installato con l'ambiente di produzione. (Mi è capitato di avere programmatori che utilzzavano una jdk 1.3, quando l'ambiente di produzione girava sulla versione 1.1.8.)
  • Client per l'accesso ai vari Development Databases configurato con tutte le informazioni necessarie
  • Client per l'accesso al Source Control Software
  • Client per l'accesso alla macchina di development (telnet, Ftp, Exceed, ecc.)
  • Se possibile l'application server per l'esecuzione ed il testing locale del codice prodotto

Testing/QA Environment: questo è una replica esatta dell'ambiente di produzione ed utilizzato dal gruppo QA (Quality Assurance) per la fase di testing di cui parleremo nel prossimo articolo.

Defect Tracking System: questa è l'applicazione utilizzata per il tracking dei bugs/difetti del sistema sviluppato. Questo importante aspetto della fase di testing verrà analizzato nel prossimo articolo.

Il Development Environment non dovrebbe avere restrizioni, cioè gli sviluppatori dovrebbero essere liberi di sperimentare, creare, modificare l'ambiente stesso. Naturalmente il buon senso detta che gli stessi sviluppatori devono coordinarsi fra di loro prima di apportare grandi modifiche all'ambiente stesso, in modo che ognuno è conscio delle conseguenze risultanti da tale modifica, evitando così spiacevoli sorprese.

Non ho intenzione di descrivere come ogni sviluppatore deve fare il proprio lavoro, questo è un fatto del tutto personale, ma vorrei soffermarmi su alcuni punti che penso siano di carattere ed utilità generale:

  • Coding Conventions

Anche se l'atto di programmare è del tutto personale, lo sviluppatore deve attenersi alle linee guida dettate dal DDD e alle convenzioni (standards) sviluppate dall'azienda. Questi standards possono semplicemente dettare la nomenclatura delle variabili, ma possono avere una complessità tale da includere: la spaziatura da utilizzare nell'identare il codice, l'uso delle parentesi, l'uso di particolari costrutti, ecc.

L'applicazione di queste convenzioni permette di aumentare, notevolmente, gli standard di qualità e di mantenibilità, fattore molto importante quando bisogna apportare modifiche a progetti sviluppati molto tempo prima.

  • Creazione delle tabelle su DB

Se nel gruppo è presente un DBA (DataBase Administrator) allora a lui spetta il compito di creare e modificare le tabelle, constraints, sequences, stored procedure, e tutto ciò che è stato descritto nel DDD. A lui spetta anche il compito di creare e mantenere gli scripts da utilizzare nella fase di migrazione in ambienti quali testing e production.

Se il DBA non è presente nel gruppo, allora ogni sviluppatore deve creare e modificare le tabelle che sono direttamente legate allo sviluppo delle componenti a loro affidate. Ognuno è responsabile della creazione e modifica di qualsiasi meccanismo che coinvolge l'uso del DB. Molto importante è il fatto che loro stessi devono scrivere e mantenere gli scripts necessari alla creazione delle tabelle e di tutti gli altri strumenti di supporto (sequences, index, relationship, ecc.). Questi scripts devono essere raccolti dal team leader e comunicati al DBA della compagnia che si occuperà di creare un'unico script per la successiva fase di release.

  • Unit Testing

Per unit testing si intende controllare la funzionalità di una unità di codice in modo isolato dal resto del sistema. Quanto grande sia questa unità dipende dalla funzionalità che si sta sviluppando e dalle dipendenze che questa ha rispetto ad altre classi.

L'idea dietro al "Unit Testing" è l'assunzione che: "se le parti che costituiscono un sistema più complesso funzionano, allora c'è una maggiore probabilità che il sistema completo funziona una volta assemblato". Lo scopo è, quindi, quello di identificare bugs prima della fase di integrazione con il resto del sistema. Inoltre, testare parti di sistema più piccole è più facile e meno costoso.

Spesso si confonde lo unit testing con il testare ogni singolo metodo di una classe, ma non è così: lo unit testing si fonda sul concetto di unità funzionale e questa può avere uno scope maggiore di una semplice classe ed includere classi multiple. Ad esempio se dobbiamo verificare la funzionalità di aggiungere dei fondi ad un conto bancario implementato con il metodo aggiungiFondo(long fondo), questo può fare uso, al suo interno, di altre classi e metodi che devono essere stati, a loro volta, testati.

Banalmente, lo unit testing ha successo, se il metodo si comporta come specificato nel DDD.

  • Development Strategies

Il project manager o il team leader possono introdurre metodologie particolari di sviluppo software come la nuova metodologia "Extreme Programming". A questo riguardo non ho nessuna preferenza e sono aperto a qualsiasi metodologia. L'unico punto che mi interessa sottolineare è che ogni metodologia di per se non porta nessun vantaggio se non si adatta al team di lavoro.

Io personalmente ho utilizzato una versione modificata della "Extreme Programming", perché il lavoro a coppie, specificata in tale metodo, proprio non funzionava con le dinamiche del gruppo di lavoro che mi era stato affidato.

Qundi prendetevi tutte le libertà del caso e modificate a piacimento le metodologie a cui siete interessati: non troverete quasi mai dei metodi che si adattano al 100% ad ogni situazione.

  • Development Deployment

Quando lo sviluppatore ha completato in tutto od in parte il codice a lui assegnato, è arrivato il momento di migrare il codice nell'ambiente di development.

Prima di migrare il codice in tale ambiente, è importantissimo salvare il codice prodotto utilizzando il Source Control Software a disposizione. In realtà questo dovrebbe essere fatto periodicamente durante lo sviluppo locale e non quando si va nel Development Environment. In ogni caso, se non avete salvato il sorgente prima, questo è un ottimo momento per farlo.

Una volta che il codice è stato migrato nell'ambiente di sviluppo, è arrivato il momento di testarlo con le altri parti del sistema.

Aspettatevi dei comportamenti anomali in questo nuovo ambiente, perché c'è una maggiore possibilità di avere scenari a cui lo sviluppatore non ha pensato. Nulla di grave, questo ambiente viene creato per scoprire problemi difficili da riprodurre nell'ambiente locale, e non come semplice passaggio formale.

Conclusioni

Voglio ancora una volta sottolineare come la fase di discovery e quella di design sono essenziali per avere una buona fase di implementazione. Il fatto di avere una lista completa di requisiti e delle loro soluzioni, riduce la fase di implementazione ad un facile esercizio di programmazione che non lascia spazio ad interpretazioni su come il sistema dovrebbe funzionare.

Se il programmatore non riesce ad avere una chiara visione sulla funzionalità da implementare o sul come implementarla, allora significa che POC o DDD (od entrambi) sono incompleti ed il team leader deve supplire a questa mancanza.

Come avete notato ho trattato la fase di implementazione in modo molto leggero e cercato di descrivere semplicemente l'ambiente migliore in cui operare e gli strumenti a disposizione che possono essere di grande aiuto.

Ho anche evitato la trattazione di particolari metodologie, perché penso che in fondo, anche in questo caso, il buon senso e sensibilità sono la migliore strategia.

MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems.
Tutti i diritti riservati. E' vietata la riproduzione anche parziale.
Per comunicazioni inviare una mail a info@mokabyte.it