Anti-pattern
In informatica, gli anti-pattern (o antipattern) sono dei design pattern, o più in generale delle procedure o modi di fare, usati durante il processo di sviluppo del software che, pur essendo lecitamente utilizzabili, si rivelano successivamente inadatti o controproduttivi nella pratica. Il termine fu coniato nel 1995 da Andrew Koenig, ispirato dal libro Design Patterns: Elementi per il riuso di software ad oggetti scritto dalla Gang of Four (la banda dei quattro), i quali svilupparono il concetto di pattern nel campo del software.
Secondo l'autore, devono presentarsi almeno due elementi chiave per poter distinguere un anti-pattern da un semplice errore logico o cattiva pratica:
- Qualche schema ricorrente di azioni, processi o strutture che inizialmente appaiono essere di beneficio, ma successivamente producono più problemi che benefici.
- L'esistenza di una soluzione alternativa che è chiaramente documentata, collaudata nella pratica e ripetibile.
Molti anti-pattern sono poco più che errori, problemi irrisolvibili o cattive pratiche da evitare quando possibile. A volte chiamati "pitfalls" (tranelli) o dark pattern (pattern oscuri), si riferiscono a classi di soluzioni di problemi reinventate in modo sbagliato.
Per descrivere in modo formale errori che tendono a ripetersi, si può individuare la forza con la quale questi si ripetono, e imparare come altre persone hanno rimediato a questi cattivi pattern.
Gli anti-pattern più comuni
(Nota: il nome in inglese è stato lasciato in quanto è quello con cui i pattern, e gli anti-pattern, sono conosciuti nella lingua italiana)
Organizzativi
- Design by committee: presenza di molte persone che contribuiscono a una progettazione, ma mancanza di una visione globale condivisa;
- Corpi tiepidi - warm bodies: aggiungere a un progetto nuovi programmatori che non riusciranno a fare quasi nulla per mancanza di esperienza su di esso;
- Paralisi da analisi - analysis paralysis: progetto fermo nella fase di analisi, ad esempio perché si sta vagliando un ventaglio di soluzioni troppo ampio senza riuscire a sceglierne una, o perché la si sta dettagliando eccessivamente;
- Sistema a tubo da stufa - stovepipe system: organizzazione in cui ogni team è isolato dagli altri, e le comunicazioni sono rese possibili solo verso l'alto o il basso della gerarchia;
Nel management
- Fumo e specchi - smoke and mirrors: mostrare una funzionalità del programma che in realtà non esiste ancora, ad esempio tramite schermate fittizie, senza che l'osservatore sappia che lo sono;
- Gestione a fungo - mushroom management: team in cui ogni impiegato è tenuto isolato, con un compito specifico, senza poter comunicare con i compagni;
- Marcia della morte - death march: progetto la cui stima è troppo bassa rispetto al requisito, che costringe i programmatori a sforzi pesantissimi e a un numero consistente di ore di straordinario, ma che è comunque destinato a fallire.
- Elefante nella stanza - elephant in the room: ignorare o minimizzare un problema anche se ovvio e appariscente, al fine di evitarlo
Di sviluppo
- Ancora da nave - boat anchor: mantenere una porzione di codice sorgente diventata inutile;
- busy waiting: ciclo continuo di attesa di un evento;
- Azione a distanza - action at a distance: modifica che impatta su parti di codice molto lontane tra loro;
- Mancato caching - caching failure: non azzerare una cache contenente un errore, dopo che esso è stato trattato;
- Carica e spara - accumulate and fire: subroutine i cui input sono variabili globali;
- Codice puzzolente - code smell: piccolo malfunzionamento, che però è sintomo di un grande problema più nascosto;
- Colata di lava - lava flow: mantenere porzioni di codice la cui rimozione è rischiosa o può causare conseguenze non determinabili;
- Complessità involontaria - accidental complexity: apparente necessità di sviluppare codice complesso, che invece sarebbe già disponibile in qualche libreria;
- Enorme palla di fango - big ball of mud: sistema costruito in modo caotico, senza una struttura riconoscibile;
- Fede cieca - blind faith: non verificare il risultato di una subroutine o il manifestarsi di un errore;
- Inerzia del codice - code momentum: presenza eccessiva di vincoli e dipendenze, che rendono difficili le modifiche;
- Inferno delle DLL - DLL hell: presenza di conflitti tra le DLL da cui il programma dipende;
- In mano al fornitore - vendor lock-in: dipendenza troppo stretta da uno specifico fornitore, non sostituibile se non a costi elevati;
- Input ad-hoc - input kludge: incapacità di gestire input non validi;
- Interblocco ricontrollato - double-checked locking: inizializzazione parziale di un oggetto condiviso tra thread;
- Interfaccia che ingrassa - interface bloat: incorporare troppe operazioni in una sola interfaccia;
- Invecchiamento rapido - continuous obsolescence: sistema le cui versioni sono troppo diverse tra loro, e che quindi invecchia rapidamente e di continuo;
- Inversione di astrazione - abstraction inversion: non esporre funzionalità utili, costringendo a reimplementarle;
- Kitchen sink: oggetto che contiene un gran numero di operazioni complesse ed eterogenee tra loro;
- Numero magico - magic number: inserire costanti negli algoritmi senza documentarne il significato o lo scopo;
- Oggetto Dio - God object: implementare una grossa funzionalità in un unico oggetto che esegue tutte le operazioni, invece che in più oggetti che si dividono il compito;
- Ottimizzazione prematura - premature optimization: scrivere codice molto ottimizzato, ma poco leggibile;
- Poltergeist: oggetto il cui unico compito è passare informazioni a un unico altro oggetto;
- Priorità alle estensioni - feature creep: aggiungere ulteriori caratteristiche al progetto, andando ben oltre il requisito iniziale;
- Problema dello yo-yo - yo-yo problem: struttura eccessivamente frammentata e quindi difficile da comprendere;
- Programmazione cargo cult - cargo cult programming: inserire una porzione di programma ignorandone scopo o principio di funzionamento;
- Programmazione copia e incolla - copy and paste programming: implementare una funzionalità simile ad un'altra copiandone e incollandone il codice piuttosto che creando una subroutine condivisa;
- Pulsante magico - magic pushbutton: pulsante che contiene anche la propria logica applicativa, invece che tenerla separata;
- Punto di vista ambiguo - ambiguous viewpoint: diagramma che indica solo le parti, ma non cosa compongono, ad esempio senza distinguere tra parti di interfaccia e di implementazione;
- Reinventare la ruota - reinventing the wheel: reimplementare un metodo che è già stato implementato, testato e ottimizzato da qualcun altro;
- Reinventare la ruota quadrata - Reinventing the Square Wheel: come reinventing the wheel, ma il risultato della reimplementazione è peggiore del metodo esistente;
- Sbagliato di uno - Fencepost (o anche off-by-one) error: partire dall'indice iniziale sbagliato in un loop (ad esempio in Java iniziare il loop su un array partendo da 1 invece che da 0);
- Software che ingrassa - software bloat: tendenza di un'applicazione ad avere programmi di installazione che crescono a dismisura;
- Spaghetti code - spaghetti code: codice con un flusso incomprensibile;
- Valori cablati - hard code: inserire costanti nel codice piuttosto che in file di configurazione;
- Valori esterni - soft code: inserire logica applicativa in file di configurazione (ad esempio con un linguaggio di comandi) piuttosto che nel codice;
- Vicolo cieco - Dead End: dover modificare una componente su cui il supporto da parte di chi l'ha fornita è cessato;
Bibliografia
- William J. Brown, Raphael C. Malveau, Hays W. McCormick III, e Thomas J. Mowbray. 1998. AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis. John Wiley & Sons ISBN 0-471-19713-0.
Collegamenti esterni
Controllo di autorità | LCCN (EN) sh00000119 · J9U (EN, HE) 987007290697705171 |
---|