Anti-pattern

De la Wikipedia, enciclopedia liberă

Un anti-pattern este un răspuns comun la o problemă recurentă, răspuns de obicei ineficient și care riscă să fie extrem de contraproductiv.[1][2] Termenul, inventat în anul 1995 de către Andrew Koenig⁠(d),[3] a fost inspirat de cartea Design Patterns⁠(d), care evidențiază o serie de așa-numite design-patternuri în dezvoltarea de software, pe care autorii le consideră a fi extrem de fiabile și eficiente.

Termenul a fost popularizat trei ani mai târziu în cartea AntiPatterns, care a extins utilizarea acestuia dincolo de domeniul proiectării de software, cu referire de această dată la orice obicei frecvent reinventat, dar care este o soluție proastă la o problemă. Printre exemple se numără analysis paralysis (o formă de încremenire în proiect), programarea cargo-cult, marșul morții, gândirea de grup și dependența de furnizor.

Definiție[modificare | modificare sursă]

Potrivit autorilor cărții Design Patterns, trebuie să fie prezente cel puțin două elemente-cheie pentru a putea identifica efectiv un anti-pattern față de un simplu obicei prost, o rea practică, sau o idee proastă:

  1. Un proces, o structură sau un model de acțiune frecvent utilizat și care, deși inițial pare a fi un mijloc adecvat și eficace de răspuns la o problemă, are, de obicei, consecințe mai mult rele decât  bune
  2. Există o altă soluție, documentată, repetabilă și dovedită a fi eficientă.

Exemple[modificare | modificare sursă]

Organizaționale[modificare | modificare sursă]

  • Analysis paralysis (Paralizarea în analiză): proiect blocat în faza de analiză, în imposibilitatea de a obține sprijin pentru oricare dintre planurile posibile de abordare
  • Bicycle shed: acordarea de importanță disproporționată unor probleme triviale
  • Bleeding edge: Operarea cu tehnologii de ultimă oră, care sunt încă netestate și/sau instabile, ceea ce duce la depășiri de costuri, sub-performanță, și/sau livrări întârziate
  • Apatia spectatorului: fenomen în care oamenii oferă mai greu ajutor unei persoane în nevoie atunci când sunt și alții prezenți
  • Cash cow: Un produs învechit, dar profitabil, care de multe ori duce la automulțumire și lipsă de entuziasm pentru noile produse
  • Design prin comisie: ceea ce rezultă când un proiect se bazează pe prea mulți colaboratori, fără o viziune unificatoare
  • Escaladarea angajamentului: Incapacitatea de a revoca o decizie atunci când se dovedește greșită
  • Gândirea de grup: O stare colectivă în care membrii grupului încep (adesea în necunoștință de cauză) să gândească la fel și să respingă punctele de vedere diferite
  • Managementul prin obiective: Managementul prin numere, concentrarea exclusiv asupra criteriilor de management cantitative, atunci când acestea sunt neesențiale sau costă prea mult
  • Micromanagement: Ineficiență rezultată din observarea, supravegherea, sau implicarea directă din partea conducerii
  • Hazardul moral: Izolarea unui decident de consecințele deciziei
  • Mushroom management: Lipsa de comunicare coerentă între management și angajați: primul este veșnic nemulțumit de activitatea celor din urmă; cei din urmă nu înțeleg niciodată ce și de ce li se cere
  • Principiul lui Peter: Promovarea continuă a unor angajați care altfel au bune performanțe până la un nivelul la care devin incompetenți, unde aceștia rămân pe termen nelimitat
  • Seagull management: Managerii interacționează cu angajații numai atunci când apare o problemă, când „intră zburând, fac multă gălăgie, aruncă cu gunoi în toată lumea, fără să rezolve nimic, după care își iau zborul”
  • Typecasting: Blocarea angajaților de succes în activități prea sigure, strict definite și previzibile, pe baza succesului lor din trecut, în loc de alocarea lor pe baza potențialului de evoluție
  • Dependența de furnizor: Construirea unui sistem care ajunge să depindă de o componentă furnizată extern.

Managementul de proiect[modificare | modificare sursă]

  • Carul înaintea boilor: Concentrarea excesivă de resurse asupra unei etape înainte de a-i veni rândul
  • Marșul morții: Toți cei ce lucrează la un proiect știu că va eșua, dar sunt obligați să continue să lucreze la el, de către managementul care refuză să înțeleagă situația
  • Regula nouăzeci-nouăzeci: Tendința de a subestima cantitatea de timp pentru a finaliza un proiect, atunci când acesta este "aproape gata"
  • Overengineering: Investirea de resurse pentru a face un proiect mai robust și mai complex decât este necesar
  • Scope creep: Schimbări necontrolate sau creștere continuă a sferei de interes a unui proiect, sau adăugarea de noi caracteristici în plus față de cerințele inițiale elaborate și acceptate (denumit și requirement creep și feature creep)
  • Fum și oglinzi: Demonstrarea de funcționalități neimplementate ca și cum acestea au fost deja implementate
  • Legea lui Brooks: Adăugarea de mai multe resurse la un proiect pentru a-i crește viteza, atunci când proiectul este deja încetinit de excesul de coordonare.

Ingineria Software[modificare | modificare sursă]

Proiectarea software[modificare | modificare sursă]

  • inversiunea abstracției: Neexpunerea de funcționalitate implementată necesară apelanților unei funcții/metode/constructor, ceea ce face ca codul apelant să reimplementeze aceleași funcționalități
  • Punct de vedere ambiguu: Prezentarea unui model (de obicei orientat obiect) fără a specifica punctul de vedere
  • Big ball of mud: Un sistem fără o structură identificabilă
  • Baze de date ca mecanism de transfer date: Folosirea unei baze de date drept coadă de mesaje pentru comunicarea interproces - acolo unde ar fi potrivit un alt mecanism mult mai mic
  • Placarea cu aur: Continuarea lucrului la o sarcină sau la un proiect care a trecut de punctul în care efortul suplimentar mai adaugă valoare
  • Interface bloat: o interfață atât de puternică încât este extrem de dificil de implementat
  • Butonul magic: Formular fără validare dinamică sau asistență la introducerea datelor
  • Race hazard: Incapacitatea de a vedea consecințele unor evenimente care, uneori, poate interfera unele cu altele

Programarea orientată-obiect[modificare | modificare sursă]

  • Modelul anemic: utilizarea unui model al domeniului fără niciun business logic. Obiectele din model nu pot garanta corectitudinea în orice moment, întrucât validarea și logica de mutație este plasată undeva în afară (cel mai probabil în mai multe locuri). Martin Fowler consideră acesta a fi un anti-pattern, dar unii nu sunt de acord că este întotdeauna un anti-pattern.[4]
  • BaseBean: Moștenirea de funcționalitate dintr-o clasă de utilitate, în locul delegării către ea
  • Dependențe circulare: Introducerea de dependențe reciproce directe sau indirecte între obiecte sau module software
  • Interfața de constante: Folosirea interfețelor pentru a defini constante
  • Obiectul-Dumnezeu: Concentrarea prea multor funcții într-o singură zonă de proiectare (clasă)
  • Haznaua de obiecte: Reutilizarea obiectelor a căror stare nu este conformă (eventual implicită) cu contractul pentru reutilizare
  • Orgie de obiecte: Neîncapsularea corespunzătoare a obiectelor, permițând accesul nerestricționat la elementele lor interne
  • Poltergeist: Obiecte al căror unic scop este de a transmite informații de la un alt obiect
  • Cuplarea în secvență: O clasă ale cărei metode trebuie apelate într-o anumită ordine
  • Problema yo-yo: O structură (de exemplu, de moștenire) greu de înțeles din cauza fragmentării excesive

Programare[modificare | modificare sursă]

  • Complexitate accidentală: Sarcini de programare care ar putea fi eliminate cu instrumente mai bune (spre deosebire de complexitatea inerentă a problemei de rezolvat)
  • Acțiune la distanță: Interacțiunea neașteptată între părți diferite ale unui sistem
  • Credința oarbă: Lipsa de control asupra corectitudinii unui bug fix sau a rezultatului unei subrutine
  • Busy-waiting: Consumul de timp de CPU în timp ce se așteaptă ca ceva să se întâmple, de obicei, prin verificări repetate în loc de transmitere de mesaje
  • Codificare prin excepție: Adăugarea de cod nou pentru a trata fiecare caz special, pe măsură ce acestea se identifică; în loc de a modifica codul pentru a produce o abordare mai generală
  • Design pattern: utilizarea de design-patternuri a fost numită anti-pattern, un semn că sistemul nu are un grad suficient de abstractizare[5]
  • Ascunderea erorilor: Prinderea unui mesaj de eroare înainte de a putea fi afișat pentru utilizator și prezentarea către utilizator a unui mesaj fără sens sau a niciunui mesaj. Se poate referi și la ștergerea stivei de apeluri în timpul manipulării excepției, ceea ce poate îngreuna depanarea.
  • Hardcodarea: încorporarea în cod ca date fixe a unor ipoteze sau a unor informații variabile
  • Cod-lasagna: Programe a căror structură este formată din prea multe straturi
  • Lava-flow: Păstrarea de cod nedorit (redundant sau de calitate scăzută) a cărui eliminare este prea costisitoare sau are consecințe imprevizibile[6][7]
  • Secvența buclă-switch: Codificarea unui set de etape succesive, folosind o instrucțiune switch într-o buclă
  • Numere magice: Includerea în algoritmi a unor valori numerice atipice și neexplicate
  • Autorepetiția: Scrierea de cod care conține modele repetitive în loc de a separa funcționalitățile recurente în funcții
  • Soft-code: Stocarea business-logicului în fișierele de configurare, în loc de codul sursă[8]
  • Cod-spaghetti: Programe a căror structură este greu de înțeles, în special din cauza utilizării eronate a structurilor de cod
  • Superstitious coding: Scrierea de cod ce tratează cazuri de eroare despre care se știe că sunt imposibile. Opusul credinței oarbe

Metodologice[modificare | modificare sursă]

  • Programarea cu copy-paste: Introducerea prin copy&paste de cod existent, în locul dezvoltării de module reutilizabile
  • Ciocanul de aur: Presupunerea că o soluție preferată este universal aplicabilă (vezi și: glonțul de argint)
  • Factorul de improbabilitate: Presupunerea că un caz de eroare este improbabil
  • Sindromul Not Invented Here (NIH): tendința de a reinventa roata (incapacitatea de a adopta o soluție existentă și adecvată)
  • Inventat aici: tendința de a respinge orice inovație sau soluție netrivială originară din interiorul organizației, de obicei, din cauza lipsei de încredere în personal
  • Optimizarea prematură: Îmbunătățiri de eficiență făcute devreme, cu sacrificiul unui design bun, a mentenabilității, și, uneori, chiar a eficienței din lumea reală
  • Programarea prin permutare (sau „programarea din întâmplare”, sau „programare prin coincidență”): Încercarea de a aborda o soluție prin modificarea succesivă a codului pentru a vedea dacă funcționează
  • Reinventarea roții pătrate: Neadoptarea unei soluții existente, și folosirea în schimb a unei soluții personalizate care se comportă mult mai rău decât cea existentă
  • Glonțul de argint: Presupunerea că o soluție tehnică anume poate rezolva o problemă mai largă
  • Dezvoltare Condusă de Testeri: proiecte software în care noile cerințe sunt specificate în rapoarte de buguri

Managementul configurațiilor[modificare | modificare sursă]

  • Infernul de dependențe: Probleme cu versiunile de produse necesare
  • Infernul de DLL-uri: gestionarea necorespunzătoare a bibliotecilor de legături dinamice (DLL-uri), în special pe Microsoft Windows
  • Conflictul de extensii: Probleme ce apar când extensii diferite de Mac OS clasic încearcă să modifice aceleași părți ale sistemului de operare
  • Infern de JARuri: Suprautilizarea de mai multe fișiere JAR, ceea ce uneori duce la probleme de versiuni și locații din cauza neînțelegerii modelului de încărcare a claselor în Java

Referințe[modificare | modificare sursă]

  1. ^ Budgen, D. (). Software design. Harlow, Eng.: Addison-Wesley. p. 225. ISBN 0-201-72219-4. 
  2. ^ Scott Ambler⁠(d) (). Process patterns: building large-scale systems using object technology. Cambridge, UK: Cambridge University Press. p. 4. ISBN 0-521-64568-9. 
  3. ^ Koenig, Andrew (). „Patterns and Antipatterns”. Journal of Object-Oriented Programming. 8 (1): 46–48. 
  4. ^ „The Anaemic Domain Model is no Anti-Pattern, it's a SOLID design”. SAPM: Course blog. . Accesat în . 
  5. ^ „Revenge of the Nerds”. In the OO world you hear a good deal about "patterns". I wonder if these patterns are not sometimes evidence of case (c), the human compiler, at work. When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough— often that I'm generating by hand the expansions of some macro that I need to write. 
  6. ^ Lava Flow at antipatterns.com
  7. ^ „Undocumented 'lava flow' antipatterns complicate process”. Icmgworld.com. . Arhivat din original la . Accesat în . 
  8. ^ Papadimoulis, Alex (). „Soft Coding”. thedailywtf.com. Accesat în .