MokaByte 61 - Marzo 2002 
Project Management
III parte - Development Phase
di
Giancarlo Crocetti
E' 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.
Voglio, ancora una volta, sottolineare che se siamo riusciti a costruire un buon POC (Proof Of Concept) ed un buon DDD, allora la fase implementativa sara' semplicemente un esercizio di programmazione che verra' attuata senza particolari difficolta'.

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 cio' 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 funzionalita' e l'ambiente in cui dovra' 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 e' quello di prestare molta piu' attenzione a questo piccolo, ma importante, dettaglio.

Un errore comune e' quello di dimenticare che i componenti da sviluppare hanno un certo grado di dipendenza gli uni con gli altri (la cui complessita' dipende dall'applicazione da costruire) e questo si traduce nell'impossibilita' 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 trovera' in enorme difficolta' lavorando senza la classe Animale.

Il primo passo e', quindi, quello di evidenziare tutte le dipendenze tra le componenti da sviluppare, e questo e' estremamente facile se nel design e' presente un buon diagramma delle classi. Il caso descritto nell'esempio precedente puo', 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 iniziera' 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, puo' 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'e' 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 e' 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 complessita' del progetto) allo scopo di verificare l'andamento della fase implementativa ("Status Meeting"). Per qualsiasi altra comunicazione o richiesta, il project manager comunichera' direttamente con il Team Leader.
A seconda dell'azienda, il team leader puo' 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 e' 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 qualita' del software prodotta.


Figura 1 - Ambiente di Sviluppo

Ci sono diversi ambienti da configurare all'inizio della fase implementativa, ed anche se questo e' piu' un lavoro da system administrator, voglio lo stesso menzionarla perche' 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 e' 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: e' preferibile avere per tutti lo stesso software e la stessa versione. Molto importante e' la compatibilita' del software installato con l'ambiente di produzione. (Mi e' 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 e' 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 e' l'applicazione utilizzata per il tracking dei bugs/difetti del sistema sviluppato. Questo importante aspetto della fase di testing verra' analizzato nel prossimo articolo.

Il Development Environment non dovrebbe avere restrizioni, cioe' 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 e' conscio delle conseguenze risultanti da tale modifica, evitando cosi spiacevoli sorprese.

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

  • Coding Conventions
    Anche se l'atto di programmare e' 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 complessita' 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 qualita' e di mantenibilita', fattore molto importante quando bisogna apportare modifiche a progetti sviluppati molto tempo prima.

  • Creazione delle tabelle su DB
    Se nel gruppo e' presente un DBA (DataBase Administrator) allora a lui spetta il compito di creare e modificare le tabelle, constraints, sequences, stored procedure, e tutto cio' che e' 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 e' presente nel gruppo, allora ogni sviluppatore deve creare e modificare le tabelle che sono direttamente legate allo sviluppo delle componenti a loro affidate. Ognuno e' responsabile della creazione e modifica di qualsiasi meccanismo che coinvolge l'uso del DB. Molto importante e' 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 occupera' di creare un'unico script per la successiva fase di release.

  • Unit Testing
    Per unit testing si intende controllare la funzionalita' di una unita' di codice in modo isolato dal resto del sistema. Quanto grande sia questa unita' dipende dalla funzionalita' che si sta sviluppando e dalle dipendenze che questa ha rispetto ad altre classi.
    L'idea dietro al "Unit Testing" e' l'assunzione che: "se le parti che costituiscono un sistema piu' complesso funzionano, allora c'e' una maggiore probabilita' che il sistema completo funziona una volta assemblato". Lo scopo e', quindi, quello di identificare bugs prima della fase di integrazione con il resto del sistema. Inoltre, testare parti di sistema piu' piccole e' piu' facile e meno costoso.

    Spesso si confonde lo unit testing con il testare ogni singolo metodo di una classe, ma non e' cosi: lo unit testing si fonda sul concetto di unita' funzionale e questa puo' avere uno scope maggiore di una semplice classe ed includere classi multiple. Ad esempio se dobbiamo verificare la funzionalita' di aggiungere dei fondi ad un conto bancario implementato con il metodo aggiungiFondo(long fondo), questo puo' 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 e' 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", perche' 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 liberta' 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, e' arrivato il momento di migrare il codice nell'ambiente di development.
    Prima di migrare il codice in tale ambiente, e' importantissimo salvare il codice prodotto utilizzando il Source Control Software a disposizione. In realta' 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 e' un ottimo momento per farlo.
    Una volta che il codice e' stato migrato nell'ambiente di sviluppo, e' arrivato il momento di testarlo con le altri parti del sistema.

Aspettatevi dei comportamenti anomali in questo nuovo ambiente, perche' c'e' una maggiore possibilita' 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 funzionalita' 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, perche' penso che in fondo, anche in questo caso, il buon senso e sensibilita' sono la migliore strategia.

Giancarlo Crocetti si e' laureato in Scienze dell'informazione all'universita' "La Sapienza" di Roma per poi conquistare il Master in Computer Science alla Rutgers University del New Jersey nel 1998. Dal 1996 vive a New York dove lavora come consulente per importanti aziende ed enti governativi come: Computer Science Corporation, United Nations, Merrill Lynch, Lockheed Martin e per il governo degli Stati Uniti.
Da piu' di quattro anni il 60% dei sistemi da lui architettati e sviluppati vengono implementati utilizzando tecnologie Java. Nel 2000 ha creato la propria azienda Nous USA inc., che offre servizi di consulenza e di training concentrate soprattutto su tecnologie Java.

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