Unreadable code example


Sometimes you meet code like this.
I don't understand even a snippet.




public class LinesJournalist extends Journalist {
    private final LinesLiner _liner;

 public LinesJournalist(LinesLiner liner) {
            _liner = liner;
 }

 @Override
 public AbstractMessage createMessageFrom(MessageFactory aMessageFactory, Fields anInput) {
     // THINK: e' sospetto che per association liner non posso passare NullLiner...
     LinesConfigurableLiner associationLiner = new LinesConfigurableLiner("", false, false);
     LinesConfigurableLiner valuesLiner = new LinesConfigurableLiner("", false, false);
            Lines lines = anInput.asLines(new FieldsSimpleLiner(new LinkSimpleLiner(associationLiner, new LinesEmptyLiner(), valuesLiner)));
            Fields fields = Fields.single(AbstractMessage.MESSAGE, lines.asLines(_liner).report());
            return aMessageFactory.make(fields);
 }
}

[Ruby] Last day of month in whenever gem



I'm using whenever gem for scheduling my own rake tasks:
https://github.com/javan/whenever

Sometimes it's useful to schedule a task the last day of the month.
The gem does not provide such alias.

The solution is the following:

job_type :only_last_day, "[ \"$(/bin/date +%d -d tomorrow)\" = \"01\" ] && cd :path && :environment_variable=:environment bundle exec rake :custom_rake_task"

every '30 10 28-31 * *' do
  only_last_day "custom_task", :custom_rake_task => "your_rake_task_name"
end


  • 30 10 28-31 * * means: try to launch the script every month at 28th,29th,30th,31th day at 10:30 am
  • if current date plus one equals 01 it means today is the last day of the month therefore the script is eligible to be run

[Rails] find not used partial ruby script

find_partial_not_used.rb
 

def string_between_markers string, marker1, marker2
  string[/#{Regexp.escape(marker1)}(.*?)#{Regexp.escape(marker2)}/m, 1]
end

all_erb_files=`find . -name '_*.erb'`.split("\n")
short_names = all_erb_files.collect {|f|
  string_between_markers f, "/_", "."
}.uniq
short_names.each {|s|
  how_many_times_is_called=`find . -name *.erb | xargs grep render | grep #{s} | wc -l`
  puts "partial #{s} not rendered in any file" if how_many_times_is_called.to_i == 0
}

[10years] Test



I principi base di una buona suite di test sono condivisi tra tutti: 

  • efficaci
  • veloci
  • manutenibili ..
Entrando in maggiore dettaglio iniziano numerose guerre di religione e filosofie differenti e non sempre conciliabili.

Code Coverage


Nel ricordare la peggiore esperienza nella scrittura di test mi viene in mente un cliente che richiedeva a tutti i team di sviluppo di raggiungere una code coverage non inferiore al 90 % . 
In quel momento i vari team avevano una copertura di circa il 20 %, ed hanno interrotto gli sviluppi per aderire alla nuova regola. 
Mi ricordo che, trovando assurda quella scelta, scrissi un test che via reflection andava a verificare tutti i getter / setter in automatico, aiutando i team a raggiungere l'obiettivo. Chiaramente era una provocazione sottile, ma formalmente corretta.

Che conseguenza ha portato l'introduzione di quella regola ?  Le logiche di programmazione si erano spostate dal codice java ai sistemi dove lo strumento di code coverage non aveva 'potere': il database con stored procedures complesse e le view jsp. 

Dire quindi che è importante avere 'tanti' test non ha chissà che valore, rispetto ad averne anche pochi ma assai efficaci.
 
Ma quale principio ci guida nella scrittura dei test? 
Il peggiore che abbia mai incontrati è 

Il principio delle scimmia



piu volte enunciato da vari colleghi incontrati nella storia: se di notte una scimmia cancella una riga a caso della tua code base , almeno un test si deve rompere.

E' un principio sensato, se non fosse che: no, non ci sono scimmie di quel genere! E' anche vero che un qualsiasi programmatore può cancellare una riga per sbaglio...ma non ha senso basare la tua strategia di scrittura di test su una paura irrazionale e statisticamente improbabile. 

Un altro principio che reputo errato è 

Gli acceptance test devono essere end-to-end



Tale principio è arrivato tardi nella mia esperienza lavorativa. I primi AT (Acceptance Test) li scrissi con Fit/Fitnesse. Avevano forma tabellare o erano narrativi, e interrogavano le logiche di business implementate nel dominio. L'input, in qualsiasi forma arrivasse, tramite chiamate http , o file di testo, o comandi in una shell, non era importante. Era importante la logica sottostante, il motore del tuo progetto.

Dopo alcuni anni ho notato questa uguaglianza logica nella testa di molti: un AT deve esercitare i sistemi "veri". Ad esempio se è una webapp devono girare in un browser.

Secondo me i test end to end non sono acceptance test nella loro idea originaria. 
Al di là della nomenclatura, anche i test di 'integrazione' con i sistemi esterni che vedo scritti in giro non vanno bene! 

I test di integrazione devono garantire che il tuo sistema sa interpretare correttamente i dati di input e che costruisce corretti dati di output, in totale aderenza ad un protocollo comunicativo. 
Ad esempio durante lo sviluppo di un ecommerce che si basa su paypal, non ha senso che i tuoi test passino dalla sandbox simulando il giro completo effettuato da un utente. 
In tal modo ti stai legando al funzionamento di un sistema che non è sotto il tuo controllo e i tuoi test stanno testando il comportamento di un altro sistema su cui non stai lavorando !
E' invece importante garantire che le chiamate http scambiate tra il tuo ecommerce e paypal siano corrette ! (ma senza necessità di una simulazione via browser) 

Riassumendo: 
  • gli AT devono esplicitare la logica applicativa. Non è necessario che siano di integrazione
  • i test di integrazione devono testare solo il protocollo di comunicazione (input e output) e basta !

Buoni principi


Per metterti in condizione di poter testare il tuo codice le dipendenze vanno iniettate. Non sono particolarmente a favore di librerie di dependency injection (non ti danno nulla in piu di farlo tu direttamente) ma non è questo il punto. E' importante non avere dipendenze dirette nel codice ! 

Portando questo principio su diversi livelli, dal singolo oggetto al modulo applicativo, riuscirai a trasformare il tuo sistema in una 'stanza dei bottoni' dove, a piacere, puoi switchare tra un database vero e uno in memoria, tra un sistema di messaggistica via code vero a uno finto, tra una dipendenza vera a una finta. 
Questo tipo di flessibilità l'ho visto applicato solo in poche occasioni in team molto maturi. Ma quando ho avuto modo di lavorare su un progetto dominato dalla 'stanza dei bottoni' il divertimento e la produttività sono stati a livelli superlativi ! 



In quasi tutti i progetti che ho lavorato ho sempre spinto verso l'adozione di 'builder' : oggetti che ti costruiscono un oggetto di dominio di 'default' , con tutte le dipendenze necessarie e che va bene nella maggior parte dei casi. 


Ad esempio in un progetto di ecommerce, è utile avere un 'productBuilder' che , a fronte della chiamata di un metodo 'build' ti dà un prodotto generico , disponibile in magazzino, con un prezzo valido, una descrizione normale etc.
La maggior parte dei test lavora su piccole variazioni in merito, ed è pertanto importante costruire una struttura che ti dia facilmente il default ma che ti permetta anche di iniettare piccole modifiche. Il product builder potrebbe essere customizzato cosi: 

new productbuilder.build()  
new productbuilder.withName('something').build()

new productbuilder.withPrice(12).build()
new productbuilder.withQuantity(5).build() ...

Una tipologia di test difficili da scrivere e ideare, ma assai utili, sono quelli relativi ad uno 'scenario' . I builder rappresentano in vitro ciò che si può fare ad un più elevato livello di astrazione: la costruzione di uno scenario 'tipo' e la possibilità di introdurre flessibilità al fine di verificare il comportamento del tuo sistema. 
Voglio rimanere volutamente generico, ma quando sono riuscito a creare dei test di scenario con i miei compagni di team ne ho trovato davvero molto giovamento! 

[10years] Studio

Lo studio: come cresce un team


In varie aziende in cui ho lavorato si dedicava un certo periodo di tempo allo studio. Era tempo impiegato fuori dalle tipiche attività di sviluppo del software.

Lavorare in un ambito informato implica la necessità di aggiornarsi e confrontarsi continuamente. Non molte aziende però valutano questa pratica importante rispetto agli usuali impegni lavorativi. Eppure senza un tempo dedicato all'esplorazione ci si tarpa le ali su tantissime possibili evoluzioni! 







Ho visto lo studio svolgersi secondo modalità assai differenti:

  • tutto il team studia insieme uno stesso argomento. Ad esempio ci siamo ritrovati a studiare i design pattern piu noti descritti in  Design Patterns . Al termine dello studio ci siamo confrontati su punti oscuri, vantaggi e soprattutto possibili applicazioni reali nel codice quotidiano.

  • ogni persona esplora un argomento che ha a cuore. Ad esempio chi è interessato al mondo javascript studia le librerie piu recenti e valuta i vantaggi di una loro introduzione, oppure alcuni si sono concentrati su aspetti meno tecnici e più rivolti al metodo, come ad esempio lo studio di altri metodi di sviluppo del software alternativi a eXtreme Programming, come Scrum e Kanban


Perpendicolarmente alla modalità di studio solitaria/ in gruppo, gli argomenti affrontati sono stati dei più disparati: 
  • argomento libero: qualsiasi cosa tu voglia esplorare: chiaramente l'apertura mentale è avvantaggiata, a scapito forse di una concreta applicazione immediata. Ad esempio studiare un linguaggio di programmazione diverso da quello che quotidianamente usi può dare forti insight sulle tecniche di programmazione ma può essere un argomento contestato perchè non presente nell'azienda in cui lavori

  • argomento legato a progetti correnti. Ad esempio ho studiato strumenti per tracciare le performance di un particolare caso d'uso. In quel momento del progetto non c'era una reale esigenza di analisi, ma affinare la conoscenza degli strumenti può tornare utile nel momento in cui si presenta un problema. 
E' difficile dire quale 'incrocio' sia il migliore, essenzialmente perchè ognuno ha i suoi pro e i suoi contro. Probabilmente la migliore soluzione che mi sentirei di proporre è di variare ogni 3/4 mesi la modalità di studio. 


Ma una invariante è necessaria ....




Vincolo: binary deliverable


Ogni studio per essere efficace deve avere uno scopo, una 'consegna' di quanto si è appreso. La piu tipica forma di condivisione della conoscenza è una presentazione al team. Ma ci possono essere molte altre forme valide: pubblicare il codice su un repository pubblico, scrivere un blog post, rispondere ad un forum etc.

Questi articoli sono appunto il mio binary delivarable per questa iterazione di studio :)  

[10years] Retrospective


Condizione necessaria e non sufficiente dei metodi agili


Per il principio già esposto che per dare importanza a un concetto bisogna dedicargli esplicitamente del tempo, i meeting di retrospettiva sono la pratica che si concentra sul miglioramento del processo di lavoro. 

Come fa un team a dirsi agile se non è guidato da uno spirito di miglioramento ? 

Un team non può professarsi 'agile' se non pratica la retrospettiva con regolarità. In alcuni team questa pratica non viene attuata con la scusa che si è sempre liberi di proporre miglioramenti o alzare una bandiera di soccorso quando ce n'è la necessità, ma in verità non ci vuole molto per capire che questo non può accadere spontaneamente. 


Problemi comuni


Nei vari anni ho trovato poche retrospettive davvero utili. Ma per quelle vale comunque la pena averne fatte tante poco efficaci ! In ogni team ci sono uno o due persone che prendono a cuore l'argomento, e tendono a parlare sempre, e uno o due persone che sono introverse o disinteressate.
E' compito di un buon facilitatore far sì che tutti abbiano il loro spazio. Il fulcro della retrospettiva è la comunicazione, principalmente verbale. Ma se non tutti hanno avuto modo di esprimere il loro parere non è stata una buona retrospettiva! 
Reputo la figura del moderatore fondamentale; probabilmente può venire a meno solo in team davvero esperti e affiatati (o forse nemmeno in quel caso?) 



Ciò che cerco sempre di evitare è l'effetto "gruppo di ascolto". Concentrandosi sui problemi, è facile che le discussioni vertino sulle mancate responsabilità di altri reparti, di altri collaboratori. 
Temi del tipo "il pm non sceglie con cura le priorità", "i sistemisti non rispondono ai ticket celermente", "gli analisti danno specifiche troppo incomplete" sono ricorrenti. Il piu delle volte sono inutili. 

Vale solo la domanda di cosa puoi fare tu e il tuo team per migliorare l'ambiente, ed eventualmente anche la comunicazione con questi reparti. 

Le azioni


E' diffuso il concetto che scopo delle retrospettive è generare azioni. 

Non sono d'accordo. 

Primo perchè le azioni dovrebbero essere meditate, e non inventante nel breve arco di tempo di una retrospettiva. Secondo perchè il valore di una retrospettiva è la comunicazione. Senza saggiare il parere di tutti su un argomento, senza una adeguata meditazione si rischia di proporre azioni deboli. E azioni deboli che non convincono verranno svolte poco impeto, risultando inefficaci. 

Se non ci sono azioni forti, risolutive, non fate nulla! 

L'iniziativa personale


La fase della retrospettiva in cui si generano azioni non deve essere la sola in cui attuare un cambiamento. Se una persona si prende a cuore un aspetto ed ha desiderio di migliorarlo, a mio avviso può e deve essere aiutato dal team in termini di tempo e supporto. Spesso mi è accaduto di ringraziare una persona per il lavoro personale che ha intrapreso spontaneamente. 

Le idee e le iniziative personali vanno incoraggiate, non soppresse!


Team agili...appesantiti


Spesso le azioni di una retrospective mirano ad aggiungere regole al processo. Dopo un po di retrospective le regole -sensate- che si sono aggiunte sono davvero tante...e il team diventa tutto tranne che agile. 

Le regole create sono da rivedere puntualmente e, a mio avviso, sono anche da limitare. 

Esempio di azioni sensate che un generico team agile propone: 
  • verifichiamo le metriche prima di ogni commit
  • facciamo code review ad ogni aggiornamento del codice
  • al termine di una funzionalità implementata ci ritagliamo x ore per pulire / documentare
  • prima di iniziare una carta scriviamo tutti gli acceptance test
  • prima di iniziare una carta la dividiamo in task
  • non si inizia una carta se ce ne sono altre in progess
  • su ogni carta c'è un responsabile fisso e ogni giorno il resto del team ruota

[10years] on-site customer

On-site customer: le scomode verità

Non ho praticamente mai visto il cliente venire a lavorare nell'ufficio del team: la maggior parte del mio tempo lavorativo l'ho passato nella sua sede. Tale scelta veniva fatta in fase contrattuale senza coinvolgimento del team di sviluppo e anzi dando per scontato che fosse la scelta piu sensata per un team XP di lavorare a stretto contatto col cliente.

Dal punto di vista teorico lavorare dal cliente dovrebbe abbattere molte barriere di comunicazione.

Verità #1: Lavorare dal cliente non facilita la comunicazione! 

La spiegazione è semplice: l'abitudine ad avere il gruppo di lavoro vicino è un freno per dedicare al team momenti specifici, perchè, in fin dei conti, è sempre disponibile. 
Tuttavia non viene così rispettata una regola d'oro per lo sviluppo del software: 

Bisogna dedicare un tempo prestabilito ad ogni azione che si reputa importante

Il sapere che si è 'sempre' disponibili perchè si è fisicamente presenti equivale a dire 'mai'. 'sempre' e 'mai' sono due estremi che si toccano spesso.



Verità #2: Spesso i clienti offrono ambienti di lavoro inadeguati.

Ho spesso lavorato in ambienti sporchi, confusi, con regole di lavoro controintuitive. Postazioni di lavoro inadeguate, tecnologie e pc obsoleti. 
Poichè il lavoro di sviluppatore richiede ben pochi requisiti, mi ha sempre stupito questo fatto. Si ha necessità di un pc potente, un monitor grosso, un ambiente non troppo rumoroso e ben illuminato e il gioco è fatto ! Spesso è più facile ricreare l'ambiente ideale nella propria sede piuttosto che dal cliente.


Lavori presso il cliente? Ecco i rischi che ti stai accollando...

  • fare formazione interna al team non è scontato. Il cliente può non capire l'importanza della formazione, e non ritenerla un'attività per cui ha pagato. Certo lo si può convincere che la crescita in un contesto che richiede aggiornamento va a suo beneficio nel lungo periodo...ma ne vale la pena? 
  • in generale, qualsiasi attività che non è pura codifica è soggetta a critiche. Fai retrospective, sessioni di design, stand up meeting, call conference, formazione ? Perchè il cliente dovrebbe supportarti in queste attività? 
  • il rischio dell'ingerenza del cliente nel processo di sviluppo è alto quando si lavora presso il cliente. Essendo lui il soggetto pagante, sarà sempre difficile per un team difendere il proprio processo di lavoro. Da un rapporto di collaborazione si passa facilmente a un rapporto di micro-management
  • talvolta il cliente vuole gli sviluppatori nella sua sede per una scomoda verità: non si fida di loro! in questo caso si ha un grosso problema di partenza, perchè viene richiesto a professionisti di cui non ci si fida di risolvere una propria esigenza. E' vero che la fiducia si conquista sul campo, ma è anche vero che bisognerebbe partire per lo meno 'neutri' in un rapporto lavorativo. Partire presupponendo che il fornitore ti voglia rubar soldi è indice di un grave problema da risolvere prima ancora di scrivere la prima riga di codice! 

La soluzione..


Lavorate presso la vostra sede. Semplice. 

[10 years] Codice (seconda parte) leggibilità,framework, falsi miti

Passaggio di consegna: una metrica fondamentale!


Per valutare un buon codice sono state proposte un gran numero di metriche. Io ne ho trovata una che reputo saggia:

Se formare una nuova persona nel tuo progetto 
richiede poco tempo, 
il tuo codice è ottimo! 

In teoria sarebbe sufficiente una suite di test di non regressione e una certa leggibilità.
Talvolta i passaggi di consegna sono considerate attività che richiedono mesi. A me pare assurdo, soprattutto considerando la complessità media dei progetti su cui ho lavorato. Quando lavori su un ecommerce, il passaggio di consegna o la formazione di un nuovo membro di un team dovrebbe essere rapida, dell'ordine di qualche giorno. Infatti a parte specificità anomale del progetto il campo ecommerce ha un dominio estremamente semplice. Tutt'altra cosa sarebbe formare una persona su un simulatore di volo o su codice geometrico 3d. 

Perchè nella realtà, nella stra grande maggioranza dei progetti il tempo di inserimento di una nuova persona è lungo ? 

Ho identificato 3 motivi principali: 
  • Ci sono troppe convenzioni orali. Per fare un task il team sa che deve rispettare delle regole, che però né sono scritte né sono automatizzate. Scoprirle tutte richiede tanto tempo e il rischio di infrangerle è grande.
  • Non c'è una fonte di informazione chiara, o non si risce ad accedervi facilmente. Ad esempio potrebbe non aver senso documentare l'architettura di un sistema, se per sua natura cambia ogni pochi mesi. Ma senz'altro ha senso poter ridisegnarla in poco tempo. La documentazione non è importante di per sé, ma è importante definire un modo con cui un nuovo entrato può reperire le informazioni necessarie.
  • Il codice è complesso. Ma il problema che risolve non lo è. Se fosse semplice la formazione sarebbe assai semplificata.

La Leggibilità: il sacro graal 



Fate fare un kata di programmazione a vari sviluppatori, ognuno valuterà l'esercizio altrui meno leggibile del proprio. 
Troppi refactoring inutili si sono fatti per il tema della leggibilità
Anche questa tematica secondo me distingue uno junior da un senior:

Il codice dev'essere leggibile come il sale: quanto basta.

E' invece importante costruire un dizionario comune all'interno del team. Quindi un termine o una tecnica che può apparire ostica ad un nuovo arrivato ha completamente senso all'interno del team consolidato. Poichè il team si allinea volente o nolente su uno stesso linguaggio è importante che esso stesso cresca (con confronti, esercizi etc) al fine di aumentare la sensibilità media. 


La mia opinione sui framework


Non amo i framework, perchè se li si usa cambia la natura del proprio lavoro che diventa da una attività creativa ad una attività organizzativa/burocratica.

Tuttavia sono andato più a fondo della pura motivazione del divertimento. La verità è che quando qualcuno decide di usare un framework per un progetto è perchè ha una scarsa concezione dei programmatori a sua disposizione. 

Scegli un framework se:
  • il tuo team discute tanto di design e poi non combina nulla
  • il tuo team mette troppi bachi in produzione
  • ogni virgola richiesta al team richiede un tempo esagerato per essere implementata
  • ci sono numerose regressioni



Il più delle volte i problemi risolti da un framework sono molto piu grandi e complessi di quanto serve davvero implementare, e il costo di imparare il framework nella mia opinione è maggiore del tempo di riscriversi un sistema custom piccolo e adatto alle proprie esigenze. 
Ho riscritto o visto riscrivere con poche righe di codice: 
  • un rule engine in ruby
  • un router in java
  • una macchina a stati di media complessità
  • un sistema di alerting di eventi asincrono estremamente scalabile
Il mio consiglio non vuole essere di usare o meno framework: non avrebbe senso. Reputo invece importante che sia il team a scegliere

Rimane un ultimo punto da chiarire: 

Come scegliere tra vari framework che risolvono lo stesso problema? 

Io reputo un framework valido se ha previsto un modo per essere testato o per testare. Ad esempio non sceglierei mai un framework per costruire applicazioni web che come *unico* strumento di test richiede Selenium.


[10 years] Codice (prima parte)


La regola delle regole del buon codice




E' simile a quella seguita nella vita day by day: ascolta tutti, ma scegli tu. 

E' importantissimo confrontarsi su buone pratiche di programmazione, sia con blog, libri e colleghi. Lo scambio di punti di vista su cosa sia un 'buon' codice è anche uno degli aspetti più divertenti del lavoro. Tuttavia tutte le regole possono essere infrante, purchè ci sia un ragionamento di base. 

Reputo questa considerazione uno dei punti che distinguono un programmatore junior da un senior. 

Un junior si appassiona a buone regole di programmazione, le applica e le considera di buon senso e funzionanti. Ma non riesce ad adattare strategie diverse a nuove situazioni. 
Un semplice esempio: in un codice scritto con paradigma ad oggetti è buona norma non esporre lo stato interno degli oggetti con metodi 'setter/getter'; tuttavia questi metodi sono molto utili nei test, non metterli implica il giocare su librerie di reflection per modificare a run time il codice compilato. La soluzione di mettere 'setter/getter', usati solo dai test, è senz'altro da preferire in un gran numero di occasioni, pur introducendo una convenzione di team di non usarli in codice di produzione. 


Le buone pratiche di programmazione


Tralascio quelle che si trovano comunemente diffuse, i vari principi SOLID, GRASP etc etc. 
Secondo molti il codice riflette il modo di pensare del programmatore. 
Se il programmatore pensa a lavorare in fretta per chiudere una funzionalità e migliorare il codice 'in futuro' non avrà problemi ad aggiungere commenti stile "TODO" nel codice. 

Ecco una breve lista di punti che reputo validi al fine di scrivere e leggere un buon codice: 
  • No Todo e Fixme nel codice. 
  • No warning del compilatore o dell'Ide. Avere un progetto con piu di una decina di warning vuol dire non usare questo strumento, quindi tanto meglio disabilitarlo. Oppure può valere la pena di configurare l'ide per valutare i warning considerati significativi, per poi correggerli.
  • Nessun commento inutile. La maggior parte dei commenti è inutile. Ma non tutti. Da agilista junior ero abituato a cancellare ogni commento. A volte indicare il perchè di una scelta, un link a un'api o un articolo, può essere utile. Commenti utili sono quelli che specificano una data e il nome dell'autore, oltre al motivo.
  • Il miglior oggetto ha un solo costruttore e un solo metodo. Sicuramente quell'oggetto sai come costruirlo e come usarlo :) certo, è una grossa semplificazione. Ma mi piace far tendere il codice verso oggetti di quel tipo. E' piu probabile che un oggetto con un solo metodo abbia una sola responsabilità. 
  • I log dell'applicazione sono importanti. Non amo i log a debug, mentre mi piace loggare ciò che vorrei leggere durante una fase di analisi. Quindi benvenuto qualsiasi formato utile ai fini di grep dei log o per tracciare tutto il ciclo di vita di un task applicativo. Ad esempio, in un contesto di ecommerce, è importante dato un numero d'ordine o un identificativo utente, poter tracciare tutto l'iter di navigazione di un processo di checkout con semplici grep dei file di log.
  • Spesso non è immediato dare responsabilità agli oggetti. Nel dubbio, meglio crearne uno nuovo, che sicuramente renderà più snelli gli altri. Il ciclo di vita di questo oggetto potrà poi essere breve, collassare o crescere in identità. 
  • Se nel tuo codice c'è anche un solo if X instanceof poniti delle domande sulle tua abilità di programmazione







[10 years] Pianificazione e priorita (seconda parte)

Priorità: considerazioni


Errore diffuso di chi ha il compito di decidere le priorità è considerare le più recenti funzionalità come le più importanti (strategia LIFO= last in first out). 
Può anche essere corretto, purchè si analizzino le 'vecchie' funzionalità messe in backlog di cui magari non si ha più memoria.

Ma al di là di ciò che viene scelto, raramente ho visto lavorare per un obiettivo

Un progetto bancario prevedeva la riscrittura totale di un sistema di pagamento elettronico. L'obiettivo del primo rilascio era quello di dirottare i pagamenti del più semplice sistema di pagamento verso il nuovo sistema, mantenendo per tutti gli altri protocolli il vecchio sistema. L'obiettivo era chiaro, ed ha permesso a pm e team di non aggiungere funzionalità speculative che non avrebbero aiutato nel raggiungimento dell'obiettivo.



Tante volte le date di consegna non sono associate a reali esigenze. Se il prodotto deve essere pronto entro il primo marzo perchè in quel giorno ci saranno pubblicità in televisione che sicuramente traghetteranno traffico, la data di consegna ha un senso. 
Spesso si creano date di consegna fittizie, passate le quali non succede niente: 

Niente di più demoralizzante aver lavorato sodo per raggiungere una data in cui non c'è reale esigenza. 

Non è mia intenzione suggerire di non creare date di consegna; il suggerimento è di associare un obiettivo.

I metodi agili generano fastidio


Il planning game ha il compito di esplicitare i rischi e gli obiettivi di un rilascio. Con quanto budget si riesce a raggiungere un set di funzionalità con ragionevole certezza. 
Il problema è che tanti manager non accettano di vedere i vincoli. Cosi le date di rilascio diventano mandatorie, e l'unica strategia suggerita più o meno esplicitamente è di ribaltare il rischio di consegna sullo sviluppatore, chiedendogli di fare straordinari.
Io non baserei il successo del mio progetto su quest' unica opzione. 

User story - le considerazioni assodate


In quasi tutti i team in cui ho lavorato si identificano le funzionalità da implementare con l'ausilio di cartoncini fisici o elettronici chiamati 'user story' o anche 'carte'. 
Anche se ho notato una certa uniformità mi piace ribadire alcuni importanti concetti oramai assodati: 

  • ogni carta necessita di un solo responsabile. Anche se il team lavora in pair programming il responsabile rimane sulla carta dall'inizio alla fine.
  • potrebbe essere utile, se il team lo ritiene, indicare in quale attività si è consumato il tempo della carta: se una carta ha richiesto 30 pomodori/coppia (ovvero circa 15 ore/coppie), quanti di questi sono stati dedicati al codice, o alla documentazione, o al deploy e così via?
  • è utile riportare a fine giornata quanto manca alla fine della carta, e notificare al resto del team se ogni sera il remaining è maggiore di quello della giornata precedente
  • ogni carta quando chiusa necessita della firma del cliente, che si assume così la responsabilità di aver verificato, assieme al team, il suo funzionamento.  





Come si velocizza il completamento di una carta? 


Talvolta un cliente chiede di accelerare il completamento di una carta e raramente ho visto sviluppatori trovare opzioni per riuscire a farlo. Certo, non è sempre possibile nè facile, ma non è nemmeno sempre impossibile.

Il classico metodo di 'divide et impera' è una buona tecnica. 

Se si segnano su una todo list tutte le micro attività si impara a poterle dare in carico a qualcun altro. Mi piace lavorare tenendo in mente che se un mio collega si libera posso sempre 'usarlo' al fine di velocizzare la chiusura di una carta.
Quindi quando si chiede: "qualcuno ha un task che posso fare?" è un buon obiettivo di team rispondere con una pletora di "io, io!!"