Anti-pattern

Da Wikipedia, l'enciclopedia libera.

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[modifica | modifica wikitesto]

(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.

Di sviluppo

  • Ancora da nave - boat anchor: mantenere una porzione di codice sorgente diventata inutile;
  • Attesa a vuoto - 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[modifica | modifica wikitesto]

  • 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[modifica | modifica wikitesto]

informatica Portale Informatica: accedi alle voci di Wikipedia che trattano di informatica