Gli anti-pattern sono errori comuni commessi nella programmazione o progettazione del software, spesso visti in chiave ironica. Come i più noti design pattern, hanno nomi evocativi che ben descrivono con pochi termini il problema.
2. Vade retro, Satana!
A chi NON è rivolto questo talk:
• A chi crede che la tecnologia migliore nell'informatica sia
il copia-incolla
• A quelli per cui “così funge”
• A quelli che “il cane mi ha mangiato i compiti”
Gianni Valdambrini – aleister@develer.com
3. Io non ne ho mai visti...
Gianni Valdambrini – aleister@develer.com
4. Anti pattern
Come ogni mostro che si rispetti, gli anti-pattern si nascondono
alla vista dei più, che non credono alla loro esistenza..
Il termine anti-pattern si riferisce a problemi ricorrenti nella
progettazione del software.
Possono riguardare ogni aspetto dello sviluppo: manageriale,
architetturale e sviluppo del codice vero e proprio.
In questo talk verrà presentata una selezione dei più comuni o
insidiosi anti-pattern, capaci di colpire anche (o soprattutto?) i
più esperti...
4 / 37
Gianni Valdambrini – aleister@develer.com
6. Analysis Paralysis
E' una (quasi) diretta implicazione del modello Waterfall.
Avviene ogni volta che viene speso troppo tempo per fare un'analisi
perfetta.
→ Questo blocca l'intero processo di sviluppo, e non produce
nessun valore per il cliente.
Soluzione: effettuare l'analisi dei componenti principali per delineare
la struttura del progetto e iniziare l'implementazione partendo dai
componenti “più importanti”. Usare test automatici per aiutare il
refactoring nei casi di analisi con lacune.
6 / 37
Gianni Valdambrini – aleister@develer.com
8. Death by Planning
“Abbiamo un piano: se lo seguiamo e non ci allontaniamo da esso
non avremo problemi”
Avviene quando la pianificazione coinvolge anche i dettagli del
progetto e, nei casi peggiori, “il piano” viene aggiornato durante lo
sviluppo per riflettere i cambiamenti.
→ I costi della pianificazione diventano eccessivi e possono
produrre ritardi nello sviluppo senza produrre alcun valore.
Soluzione: limitare la pianificazione alle parti che hanno un valore
per il cliente o che rappresentano i componenti chiave per costruirle.
8 / 37
Gianni Valdambrini – aleister@develer.com
10. Dead End
Si ha quando un componente esterno al progetto viene modificato,
e le modifiche non vengono integrate nel componente ma risultano
in carico agli sviluppatori del progetto.
→ la manutenzione delle modifiche richiede del lavoro extra
necessario ad ogni nuova versione del progetto e del
componente.
Soluzione: adottare componenti per quanto possibile standard e
diffusi o isolare le modifiche in un layer apposito (dp adapter).
10 / 37
Gianni Valdambrini – aleister@develer.com
12. Reinventing the wheel
Avviene quando un programmatore piuttosto che adottare una
soluzione già esistente decide di crearne una propria.
Due casi:
• quando si riprende il lavoro fatto da altri.
• quando il lavoro a noi richiesto è già realizzato da una libreria
esterna.
→ Nel primo caso la soluzione nuova potrà facilmente diventare
sempre più simile alla vecchia. Nel secondo, la soluzione fatta
in casa ci porterà via molto tempo e sarà peggiore della
soluzione esterna.
Soluzione: valutare con attenzione se qualcuno ha già risolto
il problema in un modo “compatibile” con le nostre esigenze.
12 / 37
Gianni Valdambrini – aleister@develer.com
14. Spaghetti Code
E' un termine dispregiativo che identifica un codice mal strutturato,
che ha subito una serie di modifiche per coprire i casi non coperti
dal codice o per gestire “eccezioni”.
→ il degradamento del codice porta a una maggiore lentezza
negli sviluppi, ad una minore leggibilità del codice e a
difficoltà di debugging.
Soluzione: effettuare refactoring per rendere la struttura del codice
chiara e facilmente espandibile.
14 / 37
Gianni Valdambrini – aleister@develer.com
16. Overengineering
Si ha quando un programma viene realizzato più robusto e complesso
del necessario, o con più funzionalità di quanto previsto.
→ il sovra-dimensionamento comporta una maggiore lentezza
nello sviluppo, difficoltà nel debugging e in generale costi
maggiori del progetto.
Soluzione: “KISS principle”, mantenere le cose più semplici possibili.
16 / 37
Gianni Valdambrini – aleister@develer.com
18. Circular Dependency
Si riferisce alla creazione di dipendenze circolari fra oggetti o
moduli/librerie.
→ causa un alto accoppiamento fra le entità che non potranno
più essere utilizzate in modo indipendente.
Si può inoltre verificare un effetto domino in cui modifiche
minori in una entità scatenano altri cambiamenti.
Soluzione: spezzare la dipendenza circolare quando possibile,
usando meccanismi di notifica (dp observer).
18 / 37
Gianni Valdambrini – aleister@develer.com
20. Cargo Cult Programming
Succede quando vengono utilizzati metodologie, design pattern
o codice senza averne compreso appieno le motivazioni e il
funzionamento.
→ il fraintendimento può causare difficoltà nel modificare il
codice (che a sua volta può portare a bug) o nel caso delle
metodologie al fallimento dovuto ad un'interpretazione
letterale delle regole.
Soluzione: è necessario comprendere appieno le soluzioni
proposte da altri, adattandole se necessario al caso in questione.
20 / 37
Gianni Valdambrini – aleister@develer.com
22. Error Hiding
Si riferisce al nascondere un errore o un'eccezione semplificando
l'errore o nascondendolo del tutto per celare la complessità del
sistema all'utente.
→ l'utente del sistema non può comunicare quale sia con
esattezza l'errore che diventa quindi molto difficile da
individuare e correggere.
Soluzione: mostrare un errore semplificato all'utente riportando
l'errore completo in un file di log o inviandolo via mail.
22 / 37
Gianni Valdambrini – aleister@develer.com
24. Yo-yo problem
E' legato in particolare alla programmazione ad oggetti.
Succede quando si deve comprendere del codice con una gerarchia
di classi così complicata che è necessario spostarsi continuamente
fra le classi per seguire il flusso del programma.
→ la frammentazione del codice rende difficile comprendere
il flusso del codice, specialmente nel caso di metodi virtuali,
e questo può a sua volta essere fonte di errori.
Soluzione: limitare la gerarchia fra classi e preferire la composizione
all'ereditarietà “selvaggia”.
24 / 37
Gianni Valdambrini – aleister@develer.com
26. Abstraction Inversion
Avviene quando dobbiamo sviluppare delle funzionalità di alto livello
ed avendo già un'implementazione più generica e complessa
decidiamo di costruire l'astrazione sopra di essa.
→ la complessità derivante dal sistema sottostante rende
difficile il debugging e lo sviluppo di nuove funzionalità.
Soluzione: scegliere con attenzione il modo di riutilizzare codice,
evitando complessità accidentale.
26 / 37
Gianni Valdambrini – aleister@develer.com
28. Gold Plating
Si riferisce alla pratica di continuare a lavorare su un progetto o
task dopo che esso ha tutte le funzionalità richieste dal cliente.
→ nella quasi totalità dei casi il cliente (e di sicuro il project
manager) avrebbe preferito che venisse sviluppata un'altra
funzionalità.
Soluzione: eseguire i task fino al loro compimento seguendo la
priorità data dal project manager / cliente.
28 / 37
Gianni Valdambrini – aleister@develer.com
30. God Object
Dovuto spesso ad un abuso dell'ereditarietà, è abbastanza
frequente nelle classi base di framework di grandi dimensioni.
Consiste nel caricare di troppe funzionalità o responsabilità (anche
etereogenee tra loro) un oggetto, che diventa quindi il “cuore” del
software.
→ comporta difficoltà di debugging, manutenzione e di utilizzo
dell'oggetto.
Soluzione: limitare l'utilizzo dell'ereditarietà e suddividere le
responsabilità secondo criteri logici.
30 / 37
Gianni Valdambrini – aleister@develer.com
32. Blind Faith
Si riferisce alla tendenza dei programmatori di non testare la
corretta implementazione di bugfix o di una modifica in generale,
per pigrizia o per una infrastruttura in cui il testing è troppo
oneroso.
→ oltre a non realizzare la funzionalità richiesta, si possono
verificare altri bug più o meno gravi generati dalla modifica.
Soluzione: utilizzare pratiche come il TDD o lo unit testing in
generale.
32 / 37
Gianni Valdambrini – aleister@develer.com
34. Copy & Paste Programming
Si riferisce alla tendenza dei programmatori di copiare del codice
esistente per implementare una nuova funzionalità più velocemente
rispetto al creare nuovo codice da zero.
→ Oltre alle classiche sviste, il codice duplicato sarà più difficile
da sviluppare ulteriormente e eventuali bug si ritroveranno
quindi in più parti.
Soluzione: generalizzare il codice mediante refactoring ed evitare
le duplicazioni (DRY principle).
34 / 37
Gianni Valdambrini – aleister@develer.com
35. Photo & Artworks Credits
Kassandra Igolka
Davide Bellocchio
Jason Chan
Justin Holzworth
Ellie Phillips
Ben Bohane
Henrik Moses