Codul tău e de nimic și te urăsc

Articol original: jml.io

Dinamica Socială a Recenziilor de Cod

Jonathan Lange, septembrie 15, 2008

Citiți traducerea în ucraineană (mulțumesc Alyona Lompar!)

Acest articol e tradus în limba rusă de către Ivanka de la Coupofy.com

Rezumat

Recenziile de cod pot fi minunate, de mare folos, dar și incredibil de descurajatoare. Acest articol examinează cum puteți scrie recenzii de cod pentru proiectele dumneavoastră fără a vă fi provocate instinctele din categoria ”luptă sau fugi”.

Vom examina rapid de ce ar trebui să scriem recenzii de cod ca mai apoi să ne focusăm pe dinamica socială a procesului de evaluare a codului, în special în ceea ce ține de proiectele cu sursă deschisă. Într-o anumită măsură, ceea ce face codul cu sursă deschisă atât de grozav (iar uneori intimidant!) este că acesta poate ajunge în vizorul experților din întreaga lume.

Examinăm aici efectele pe care le pot avea diverse tehnologii asupra culturii de recenzare a codului, ce se poate obține de fapt prin recenzii, cum au loc recenziile în alte discipline. La fel, evidențiem unele capcane în care e foarte simplu de căzut.

Introducere

Recenziile de cod sunt cu noi deja de mult timp, fiind parte a mișcării pentru Software Liber de la bun început: cel puțin sub forma celor cu drepturi de commit revizuind patch-uri ale celor lipsiți de acest privilegiu.

În ultimii ani, recenziile de cod au căpătat o nouă importanță. Programarea Extremă a promovat ideea programării în pereche (o modalitate de recenzie continuă a codului)  și multe proiecte cu sursă deschisă acum necesită ca toate patch-urile să fie verificate, indiferent de nivelul de profesionalism al autorului.

Fiecare din aceste proiecte au abordări diferite față de recenzie: diferite instrumente, diferite procese și diferite scopuri, ceea ce duce la un grad diferit de presiune asupra comunităților de dezvoltatori de software.

Acest articol explorează deciziile pe care aceste proiecte le-au luat și presiunile sociale și stimulentele care rezultă din aceste decizii. Articolul la fel identifică potențiale probleme în procesul de recenzie și oferă sugestii pentru evitarea acestor probleme. Acest text nu este conceput ca un studiu academic riguros; mai curând e o colecție de opinii bine gândite  menite să ducă la alte reflecții, cercetări și experimentare.

Ce este o recenzie de cod?

În termeni foarte simpli, o recenzie de cod este ceea ce se întâmplă când cineva examinează codul și face comentarii în privința acestuia.

Acest articol se focusează pe recenziilepre-merge” (în traducere: ”pre-contopire”) – recenziile cărora sunt supuse patch-urile înainte de a ajunge la etapa principală de dezvoltare. Procedura clasică în cazul dezvoltării Software-lui Liber arată astfel: un dezvoltator nou trimite un patch pe o listă de adrese electronice. În unele proiecte, procesul de recenzare pre-merge continuă chiar și pentru dezvoltatori experimentați (spre exemplu, Twisted, Bazaar, Linux).

Există așa chestie ca recenzii post-merge (în traducere: ”post-contopire”). Acestea au loc frecvent în proiectele de tip Software Liber când cineva include un commit suspect în trunk. În general, recenzentul răspunde la notificarea asociată cu respectivul commit și evidențiază eroarea.

Recenziile pot fi efectuate și ca un fel de inspecție aleatoare. Ca parte a acestei abordări, un programator senior inspectează o parte anume a bazei curente de coduri și lasă comentarii despre structura și calitatea ei.

Unele recenzii sunt involuntare. Acestea tind să fie generate noaptea târziu, când un programator descifrează codul într-un colț obscur al proiectului, posibil încercând să repare o eroare. Aceste recenzii de cod sunt deseori caracterizate de un limbaj grosolan, comentarii furioase și nu sunt în genere de ajutor autorului original, care s-ar putea în genere să nu le vadă niciodată.

Ce pot realiza recenziile?

Pentru unii oameni, recenziile de cod fac parte din aceeași categorie ca și documentația, dezvoltarea bazată pe testare și tărâțele: lucruri bune dar plictisitoare cu care ne răsfățăm mai rar decât ar trebui s-o facem.

Spre deosebire de cerealele bogate în fibre, recenziile de cod pot avea beneficii diverse dar deseori concurente. În procesul recenzării în cadrul unui proiect, este important să evaluăm care dintre aceste beneficii contează cu adevărat.

Impunerea conformității

Recenziile de cod sunt importante pentru a ne asigura că tot codul sursă arată la fel. Aceasta include convențiile de denumire, ortografie corectă în comentarii și utilizarea consecventă a API-urilor interne.

Asigurarea calității

Recenzarea codului în prealabil oferă șansa de a depista erorile înainte ca acestea să înceapă a afecta utilizatorii. Un recenzent este mult mai distanțat emoțional față de cod ceea ce-l face să fie mai critic în evaluarea acestuia, iar aceasta, la rândul ei, duce la o probabilitate mai mare de depistarea a erorilor.

Sporirea clarității

Dacă o bucată de cod a fost evaluată de altcineva, atunci există cel puțin doi oameni în această lume care sunt în stare să o înțeleagă.

Un recenzent este mai distanțat de acest cod inclusiv din punct de vedere intelectual și prin urmare, poate identifica presupunerile ascunse și deciziile neclare.

O bază de coduri cu un nivel înalt de claritate permite celor proaspăt veniți să înceapă a contribui în mod rapid, ceea ce este îndeosebi de important pentru proiectele cu sursă deschisă, care se bazează în mod exclusiv pe efortul voluntarilor.

Educarea recenzenților

Dacă tot codul trebuie evaluat, atunci fiecare patch oferă o șansă de a învăța despre o parte a bazei de coduri pe care recenzentul nu o mai văzuse înainte. Aceasta înseamnă că un proces de recenzie poate fi exploatat pentru a face schimb de cunoștințe despre baza de coduri în interiorul unei comunități.

Evaluarea codului de către o pereche de ochi neimplicată anterior poate fi o binecuvântare incertă: uneori va duce la mult mai multă claritate, iar alteori va rezulta în recenzii superficiale.

Balansarea priorităților

Întrucât dezvoltatorii unui proiect deseori au diferite priorități, recenzentul deseori va avea priorități diferite de cele ale autorului. Cineva poate adăuga un patch care îmbunătățește performanța unui API central, ca mai apoi să fie nevoit să justifice de ce acest lucru e mai important decât păstrarea compatibilității inverse. Recenzia de cod forțează această discuție să aibă loc înainte ca schimbările să fie introduse în trunk.

Educarea unor programatori mai buni

O recenzie de către un programator reprezintă o oportunitate pentru a face o mică incursiune în modul de gândire al acestui programator, iar expunerea îndelungată la modul de gândire al altor programatori extinde și dezvoltă propria gândire. Recenzenții pot sugera tehnici despre care autorii nu au mai auzit înainte. Ei pot acorda întrebări la care autorul nu s-a gândit niciodată. Ei pot indica o cale mai simplă pe care autorul a omis-o.

Pe de altă parte, procesul de recenzare a codului îl impune pe recenzent să clarifice ce reprezintă exact un cod bun.

Sumar

Dinamica recenziilor de cod va varia în dependență de care dintre aceste scopuri are cea mai mare importanță. Dacă recenziile sunt în mare parte orientate spre asigurarea calității codului, atunci recenziile vor lua mai mult timp și vor fi mai minuțioase, întrucât recenzenții vor încerca să identifice erori, probleme de performanță, etc. Dacă recenziile sunt orientate în mod primar spre sporirea clarității, atunci recenziile for fi mai scurte, vor pune mai multe întrebări și vor tinde să presupună că patch-ul este bine testat și bine motivat.

Deciziile

Există niște întrebări importante care necesită un răspuns atunci când se stabilește un proces de recenzare. Aici, examinăm unele dintre aceste întrebări și vedem ce răspunsuri oferă la ele proiectele Bazaar, Launchpad și Twisted.

Cine sunt recenzenții?

Probabil cea mai importantă întrebare la care trebuie să răspundă un proiect este ”Cine sunt recenzenții?” În majoritatea proiectelor cu sursă deschisă, recenzenții sunt atrași din comunitatea celor care au contribuit cel mai mult, deși mecanismul exact variază.

Patch-urile la proiectul Bazaar trebuie aprobate de către doi dezvoltatori de bază, definiți ca oamenii care pot plasa aceste patch-uri în trunk. Aceasta asigură că fiecare patch este evaluat de către cineva cu expertiză și la fel asigură un nivel de comunicare de bază între dezvoltatori.

Launchpad are o echipa de recenzenți care este o subdiviziune a echipei generale de dezvoltare a Launchpad. Echipa de recenzie vrea ca toți dezvoltatorii să fie recenzenți, dar are și un proces prin care dezvoltatorii trebuie să fie ”tutelați” înainte de a deveni recenzenți cu drepturi depline. Procesul de ”tutelare” asigură că recenzenții proaspeți au pe cineva la care să se adreseze atunci când nu sunt siguri și că prioritățile de recenzare ale Launchpad (claritatea codului, asigurarea unui proces rapid de recenzare) sunt respectate de toți recenzenții.

Twisted permite oricui să lase recenzii atâta timp cât persoana nu a fost implicată în scrierea patch-ului. Această idee destul de ingenioasă împiedică fenomenul de ”gândire de grup” care ar putea avea loc între autor și recenzent. Dezavantajul acestei abordări este că există o diferență enormă între recenzenți. În plus, când recenziile sunt sarcina fiecăruia, ele în scurt timp devin sarcina nimănui.

Care forum?

Twisted efectuează recenziile de cod utilizând tichete de eroare. Bazaar efectuează recenziile prin intermediul unei liste de adrese electronice. Launchpad face recenziile prin intermediul unei liste de adrese electronice separate dedicate doar pentru recenzenți.

Abordarea adoptată de Twisted este un exemplu al UQDS (“Ultimate Quality Development System”). Recenziile sunt înfăptuite prin utilizarea unor tichete, astfel că pagina web asociată cu tichetul devine autoritatea canonică pentru toată informația despre o anumită corecție de eroare sau despre un anumit element funcțional adăugat. Astfel, pe lângă faptul că informația relevantă este adunată într-un singur loc, se evită discuțiile ineficiente și dezbaterile înverșunate cu participarea oamenilor care nu sunt implicați cu adevărat. Acest beneficiu vine cu un dezavantaj la fel de important: recenziile sunt rareori citite de către altcineva decât autorul patch-ului, ceea ce facilitează aplicarea diferitor standarde de către diferiți recenzenți. Dacă recenzia abordează întrebări importante, acestea sunt greu de adus în atenția unei comunității mai vaste. Regretabilul sistem de poștă electronică al Trac face dificilă urmărirea unei discuții.

Bazaar trimite recenziile pe lista generală de adrese electronice, suplimentat cu un instrument special adaptat de monitorizare a patch-urilor denumit Bundle Buggy. Întrucât atât recenziile cât și patch-urile sunt trimise tuturor dezvoltatorilor prin email, discutarea patch-urilor tinde să fie mult mai deschisă decât în cazul Twisted. Numărul mare de patch-uri face mai dificilă urmărirea corespondenței electronice și se întâmplă destul des ca firul discuției în legătură cu o recenzie anume să se transforme într-o conversație lungă și întortocheată.

Lista separată de adrese electronice a Launchpad facilitează filtrarea conversațiilor generale legate de dezvoltarea de software de cele asociate cu recenziile de cod, asta în timp ce permite părților terțe să urmărească recenziile altor persoane. În practică, aceasta înseamnă că Launchpad preia din avantajele și dezavantajele ambelor abordări.

În timp real sau offline?

Efectuarea recenziilor de cod în mod asincronic diferă foarte mult de efectuarea recenziilor în timp real.

În cadrul recenziilor de cod asincronice, așa ca cele efectuate prin email, recenzentul are timp să formuleze comentariile în mod diplomatic. În mod similar, autorul este în stare să răspundă la fiecare item în ordinea în care consideră de cuviință.

Recenziile de cod în timp real posedă toate avantajele și dezavantajele unei conversații naturale: neînțelegerile pot fi identificate și corectate în mod rapid; nu trebuie de așteptat mult timp răspunsul celeilalte părți. Desigur, discuția riscă mult mai mult să devină aprinsă, fiind mai dificilă separarea emoțiilor de fapte. La fel, este mai dificil să-ți dai seama când a luat sfârșit. Când primiți un email cu o recenzie a codului, puteți evalua imediat volumul conținutului din acel email, pe când conversațiile în timp real nu oferă în prealabil o delimitare clară a timpului care necesită a fi investit.

Cine soluționează disputele?

Există momente când autorul crede una despre patch, iar recenzentul crede cu totul altceva și nici un volum de argumente din partea ambelor părți nu pare să ducă la o opinie convergentă. Spre exemplu, într-un patch, autorul a considerat că:

  [item] = singleton_list

reprezintă un procedeu clar de obținere a singurei valori dintr-o listă care are în mod garantat o singură valoare. Recenzentul a considerat că acest procedeu nu este clar și a sugerat:

 assert len(singleton_list) == 1, \ “List should have only one value: %r” % (singleton_list,) item = singleton_list[0]

În pofida argumentelor convingătoare ale ambelor părți, nici una nu e dispusă să cadă de acord. Ce e de făcut? Cine rezolvă disputa?

Bazaar adoptă poziția că autorul patch-ului are ultimul cuvânt în subiectele aflate în dispută. Twisted zice că recenzentul are ultimul cuvânt, iar Launchpad are un recenzent superior care are un vot decisiv în astfel de situații.

Dacă autorul are ultimul cuvânt, rata dezvoltării va fi mai rapidă în detrimentul uniformității și posibil al calității. Dacă recenzentul are ultimul cuvânt, patch-urile vor fi finalizate mai lent, (recenzentul niciodată nu este la fel de interesat ca autorul ca aceasta să se întâmple), în schimb vor fi verificate mai riguros.

Lucruri proaste

Ad hominem

Aceasta ar trebui să fie de la sine înțeles: efectuați recenzia codului, nu a autorului. Comentariile la adresa persoanei doar vor îngreuna pentru ea aplicarea în practică a criticilor în adresa codului său.

Când lăsați comentarii negative, referiți-vă la ”patch” sau ”ramură”, nu la om. Spre exemplu, ”Ai introdus o eroare în get_message” devine “acest patch introduce o eroare în get_message”.

Așteptări Neclare

Dacă tot ce spuneți este ”acest patch introduce o eroare în get_message”, atunci ați eșuat ca recenzent. Scopul este să îmbunătățiți codul, nu să oferiți o serie de ghicitori autorului.

În urma citirii recenziei, autorul urmează să fie în stare să înțeleagă cum să abordeze fiecare item și să știe când a soluționat toți itemii. Recenziile fără așteptări clare devin discuții neterminate despre patch, ceea ce uneori are mai curând scopul de a satisface recenzentul decât cel de a îmbunătăți codul.

Confundarea preferințelor personale cu valoarea obiectivă

Aceasta este o problemă valabilă pentru toate tipurile de recenzii. Criticii de film, editorii literari, recenzenții academici – toți cad pradă acestui fenomen.  ”Ceea ce-mi place mie” nu este în mod necesar echivalent cu ”ceea ce e bine”, deși, în parte, a deveni un programator mai bun înseamnă a-ți alinia mai bine preferințele cu realitatea. ”Ceea ce nu-mi place” are probabil încă mai puține șanse să însemne ”ceea ce e rău”.

Când revizuiți un patch perfect acceptabil care rezolvă o problemă folosind programarea în stil imperativ, nu criticați doar din cauza că nu este într-un stil mai funcțional. Dacă o faceți, transformați procesul de recenzie într-un joc dea ”ghici ce îi place recenzentului” în loc de ”scrie un cod bun”.

Recenzenții pot evita această capcană formulând comentariile de recenzie ca întrebări: ”Ai luat în considerare utilizarea unui stil mai funcțional?”, ”De ce nu folosești expresii regulate pentru a rezolva această problemă?”, etc.

Vezi la fel ”Un feedback specific este un feedback bun”.

Dacă tot sunteți acolo…

Când evaluați codul, este tentant să cereți autorului să repare alte probleme care se regăsesc în aceeași porțiune de cod. Dacă nu aveți grijă, totul poate evolua rapid într-un exercițiu de transformare a acestei porțiuni de cod în una perfectă, luând în considerare că inițial, atât autorul cât și recenzentul voiau doar să îmbunătățească un pic codul.

Soluția în cazul dat este să apreciați obiectiv măsurile de îmbunătățire pas cu pas (vedeți, ”Mai bine este mai bine, perfect este imposibil”).

Obstrucționism

Cuvântul englez ”Filibustering” este un termen politic American care se referă la prelungirea fără capăt a dezbaterilor în legătură cu un proiect de lege pentru a împiedica adoptarea acelui proiect de lege. Fenomenul are loc uneori în cadrul proiectelor Software Liber, pentru împiedicarea implementării anumitor patch-uri.

Uneori, efectele de obstrucționare pot avea loc involuntar. Un recenzent respinge un patch pentru că nu prevede teste unitare, autorul întreabă ”cum pot face testare unitară pentru acest cod?”, iar recenzentul nu mai apare să răspundă la întrebare.

Pe lângă faptul că este un proces neplăcut, autorul este lăsat cu o ”temă pentru acasă” în așteptare, ceea ce îl încetinește în procesul de elaborare a patch-urilor.

Vezi, ”Așteptări neclare” și ”Un feedback rapid este un feedback bun”

Lucruri bune

Un Feedback specific este un feedback bun

Indicați linia exactă a codului care ar putea fi îmbunătățită. Spuneți clar ce nu este în regulă cu ea. Sugerați o modalitate prin care se poate de îmbunătățit. Asigurați-vă că autorul își va da seama când problema va fi rezolvată.

Un feedback rapid este un feedback bun

Odată ce autorii prezintă patch-urile pentru recenzie, aceștia nu mai pot face nimic atâta timp cât recenzentul nu răspunde. Efectuați recenziile operativ pentru a nu permite ca atenția autorilor să devieze prea mult.

Mai bine este mai bine, perfect este imposibil

Niciun patch nu va fi perfect și niciun patch nu va repara toate problemele existente într-un cod. Nu tindeți spre perfecțiune ci spre îmbunătățiri graduale (pas cu pas).

Fiți recunoscători

Cineva tocmai a încercat să vă îmbunătățească produsul, investind resurse cognitive, efort și creativitate pentru a vă ajuta, iar acum au expus rezultatul muncii lor pentru critici.  Mulțumiți-le!

Divmod are o politică de a spune mereu un lucru bun în fiecare recenzie de cod. Întotdeauna se găsește ceva bun de spus, chiar dacă acel ceva este ”Sunt bucuros că cineva examinează această porțiune de cod”.

Puneți întrebări

Recenzenții nu pot greși punând întrebări. În cel mai rău caz, autorul va veni cu un răspuns evident. În cel mai bun caz, atât autorul cât și recenzentul vor învăța ceva nou.

Concluzie

Recenziile de cod oferă o oportunitate minunată de a evolua ca programator și de a îmbunătăți software-ul pe care îl scriem. Există multe alegeri pe care un proiect le poate face în ceea ce privește modul în care se efectuează recenziile și ce pot obține acestea. Reflectând cu grijă la modul în care tehnologiile și procesele afectează interacțiunile de bază dintre oameni în cadrul procesului de recenzie, proiectele cu sursă deschisă pot evita capcanele care-i sperie pe începători sau care îi demoralizează pe cei ce contribuie de ani buni și pot în schimb să se focuseze pe construirea celui mai bun software posibil.

Lecturi Suplimentare

Acest eseu e făcut disponibil sub licența Creative Commons Sharealike Attribution CC-BY-SA.