Lannisterii își plătesc întotdeauna datoriile. Care este motto-ul Lannister? Yuri Boldyrev îl insultă pe bloggerul sub-Kremlin Rogers

Practici tehnologice de management al datoriilor într-o singură echipă


În urmă cu aproximativ un an, echipa noastră a trecut de la o fază de creștere rapidă a caracteristicilor la o dezvoltare mai fluidă, cu accent pe îmbunătățirea calității. În acest moment, produsele noastre au acumulat o cantitate considerabilă de soluții suboptime, cod urat și biblioteci învechite. Trebuia făcut ceva în legătură cu toate acestea.


Până în prezent, am reușit să construim un proces care face ca lupta împotriva datoriilor tehnice să fie previzibilă, nedureroasă și inevitabilă.


Ce am obtinut ca rezultat:

  • Echipa este fericită. Retrospectiva de lansare include în mod regulat puncte pozitive despre îmbunătățirea tehnologiei și reducerea datoriei tehnice.
  • Pentru mai multe lansări trimestriale la rând, am reușit să creștem funcționalitatea fără a crește numărul de linii de cod din proiect. Eliminarea codului inutil și simplificarea a ceea ce era necesar a redus dimensiunea bazei de cod pentru funcționalitatea existentă. Și această reducere a coincis în mare măsură cu noul cod care implementează noua funcționalitate.
  • În timpul refactorizărilor și modernizărilor, produsul este întotdeauna în stare de funcționare. La fiecare două săptămâni lansăm o versiune intermediară complet funcțională.

Să vă spun cum am reușit acest lucru.

Ce este datoria tehnică

Definiția mea de lucru a datoriei tehnice este cantitatea de muncă care trebuie făcută pentru ca un proiect să îndeplinească viziunea echipei despre ceea ce este grozav. Rețineți că datoria tehnică poate apărea nu numai din cauza utilizării liberale a cârjelor în dezvoltare, ci și din cauza schimbării ideilor despre frumusețe. De exemplu, practicile comune din industrie s-au schimbat. Sau dezvoltatorii s-au îndrăgostit de OOP și s-au îndrăgostit de programarea funcțională. Sau cadrul cândva la modă nu mai este un tort și a devenit dificil să găsești specialiști care ar dori să scrie pe el.


Cu toate acestea, principala cauză a datoriei tehnice este entropia în toată diversitatea ei. Teste unitare dezactivate, comentarii învechite care au pierdut contactul cu codul, decizii arhitecturale nereușite, implementare de caracteristici pe care nimeni nu le mai folosește, o bază pentru un viitor care nu a venit și multe, multe altele.


Rezultă că apariția datoriilor tehnice este inevitabilă în orice proiect de lungă durată.

Când datoria tehnică nu este o problemă

De ce datoria tehnică este proastă? Mărește costul dezvoltării ulterioare datorită mai multor factori:

  • Viteza de implementare a noilor funcționalități este redusă.
  • Probabilitatea regresiilor la corectarea defectelor crește.
  • Procesul de dezvoltare devine mai puțin previzibil și, prin urmare, mai puțin gestionabil.
  • Procesul de introducere a unui nou dezvoltator în proiect se prelungește.

Această pierdere este uneori numită „dobândă pentru datoria tehnică”


Există situații în care aceste pierderi sunt mai ieftine decât eliminarea datoriei tehnice:

  • Sfârșitul vieții proiectului este aproape. Rețineți, acesta nu este sfârșitul adăugării de funcționalități, ci momentul în care puteți înceta să pierdeți eforturile programatorilor și pe suport. În această categorie sunt incluse și prototipuri unice, demonstrații unice pentru expoziții etc.
  • Valoarea timpului de dezvoltare acum este mult mai mare decât se aștepta în viitor. Remedieri urgente la un termen limită fix, startup-uri care rămân fără bani din următoarea rundă de finanțare etc. În astfel de cazuri, repararea datoriilor tehnice poate fi amânată până când căldura momentului se răcește. Sunt proiecte care nu ies dintr-o stare de urgență, dar sfaturile din acest articol tot nu le vor ajuta.

Ce să faci cu datoria tehnică? Abordări eșuate

Abordarea nr. 1. „Nu avem timp, eliberarea trebuie depusă ieri”

Dorința de a respecta termenul de mâine cu orice preț, în detrimentul vitezei de dezvoltare poimâine.


Uneori, o structură prefabricată din cârje este o alegere corectă în mod obiectiv. În practica mea, acest lucru a fost exprimat cel mai clar când am făcut versiuni demo pentru expoziții. Data evenimentului este strict fixată; dacă nu ați ajuns la timp pentru o expoziție importantă, următoarea încercare va fi într-un an. În acest caz, puteți afișa produsul „din mâinile tale”, evitând cu atenție toate erorile. Ca inginer, este neplăcut pentru mine să fac astfel de proiecte, dar cârjele din ele sunt justificate.


Când faci un produs care va dura mult timp, totul este diferit. Respectarea termenului limită din cauza soluțiilor tehnice dubioase este o plăcere costisitoare. Costul total este:

  1. de la punerea în aplicare a cârjei în sine,
  2. de la înlocuirea sa ulterioară cu o soluție cu drepturi depline,
  3. din suferința de a avea o cârjă între punctele anterioare.

Al doilea punct este foarte ușor de subestimat și există riscul să nu ne gândim la al treilea, cel mai scump deloc.


Când întâlnești un lider tehnic cu un ochi tremurător la o conferință, se poate dovedi că a fost coșmarul depanării la nesfârșit a unui design făcut din cârje care l-a adus în această stare.


Abordarea nr. 2. „Da, aici trebuie să aruncăm totul și să scriem din nou”

Cu cât situația datoriei tehnice este mai proastă, cu atât mai puternică este tentația de a îngropa întregul cod al proiectului și de a scrie totul din nou. Aceasta este una dintre greșelile clasice care poate ucide întregul proiect.


Subiectul este atât de bine tratat în celebrul articol al lui Joel Spolsky încât nu văd niciun rost să-mi prezint propriile argumente.

Abordarea nr. 3. „Vom refactoriza noaptea și în weekend, astfel încât managerul să nu afle.”

Argumentarea necesității eliminării datoriilor tehnice în ceea ce privește beneficiile de afaceri nu este întotdeauna ușoară. Echipa de dezvoltare poate fi tentată să ocolească marginile aspre și să înceapă o refactorizare majoră pe loc. Acest lucru se poate face în timpul orelor nelucrătoare, în pauze între alte sarcini sau „la coada” altor sarcini prin umflarea estimărilor.


Ce e rău în asta? Oh, o grămadă de lucruri:

  • Transparența redusă subminează încrederea dintre management și echipă. Adesea, încercările ulterioare de a corecta situația prin impunerea disciplinei și strângerea șuruburilor vor duce la o deteriorare suplimentară a muncii în echipă.
  • O situație înrădăcinată în care prioritățile echipei și ale managementului sunt conflictuale provoacă demotivare de ambele părți.
  • Fructele refactorizării sunt incluse în produs în moduri imprevizibile și provoacă erori de regresie acolo unde nu sunt așteptate. În echipele conștiente, acest lucru duce la o încărcare bruscă și neplanificată a QA. În inconștient, intră în producție și se defectează acolo.

După ce echipa folosește această rețetă, ochii conducerii încep să treacă.

Principiile noastre

1. Adăugați sarcini tehnice la restanța generală

Există o serie de modele în viața sarcinilor din proiecte:

  • O sarcină care nu este în așteptare are mai puține șanse de a intra în muncă.
  • O sarcină fără o formulare clară are mai puține șanse de a intra în muncă.
  • O sarcină care nu poate fi estimată cu un grad ridicat de încredere are mai puține șanse de a intra în muncă.
  • O sarcină mare va aștepta mai mult în coadă decât una mică.

Maxim Dorofeev vorbește foarte bine despre aceste lucruri în „Tehnica lui „Empty Inbox Technique”


Pentru a preveni acumularea datoriilor tehnice, lucrările de eliminare ar trebui finalizate ținând cont de principiile enumerate mai sus.


Toate sarcinile, cu excepția celor mai mici, sunt listate în stoc. Astfel, ei au șansa de a se face nu numai în timpul liber, ci și ca parte a muncii planificate. În plus, astfel de sarcini sunt mai greu de pierdut complet din vedere - restanța este analizată mai des și mai atent decât la TODO din cod, bucăți de hârtie pe monitor, pagini wiki abandonate, șervețele pătate de ceai cu diagrame și altele. surse de informare.

  • Dacă în cod există o TODO non-trivială, aceasta conține un link către sarcina din backlog. Verificăm conformitatea cu acest principiu la revizuirea codului și nu acceptăm TODO complexe fără referințe.

    S-ar putea să existe o dramă în spatele comentariului.

    Odată, lângă un astfel de TODO scria: „Crânja. Product Ownerul m-a pus să o fac. Îndepărtați cât mai curând posibil.”

  • Când un dezvoltator își dă seama că un loc necesită refactorizare, el creează o problemă în restanță.
  • Când un dezvoltator are dorința de a îmbunătăți platforma, el creează o sarcină în backlog.
  • Planurile arhitecturale pe termen lung sunt puse în așteptare sub formă de sarcini separate, de îndată ce există suficientă certitudine cu privire la cel puțin primii pași.

Atâta timp cât astfel de modificări rămân ieftine în ceea ce privește costurile de dezvoltare și cantitatea de testare necesară, ne putem îmbunătăți treptat baza de coduri fără a întrerupe obiectivele de afaceri sau a introduce riscuri suplimentare.

2. Planificați poveștile tehnice pe baza priorităților de afaceri

Dacă un copac a căzut în pădure, dar nimeni nu l-a auzit, a existat un sunet? Dacă există cod prost într-un proiect, dar acel modul nu va trebui niciodată schimbat, există datorii tehnice?


Cred că atunci când un programator consideră că este neplăcut să se uite la un modul vechi, aceasta în sine nu este o problemă foarte mare. Mult mai rău este ceea ce se întâmplă atunci când trebuie să adăugați o nouă funcționalitate la acest modul sau să o extindeți pe cea veche. În comparație cu efectuarea de modificări la codul bine scris, astfel de sarcini sunt mai probabil (și mai probabil să depășească estimarea inițială) și conțin mai multe erori. Uneori mult mai mult. Pentru a ne proteja de aceste tipuri de probleme, încercăm să programăm refactorizările astfel încât acestea să fie făcute înainte de a scrie noi funcționalități în același loc.


Dacă modificările de funcționalitate și refactorizările par mici, se pot face împreună. Dimensiunea selectată empiric a sarcinii pentru care această abordare va fi optimă este de 3 zile de lucru pentru un dezvoltator sau mai puțin. Când este clar că există mai multă muncă, aceasta este împărțită în refactorizare, menținând în același timp comportamentul actual și implementând noi funcționalități.


Astfel, ordinea de lucru pentru eliminarea datoriilor tehnice este determinată de ordinea sarcinilor de afaceri din restanță.


Principiul „priorităților de afaceri” are o altă aplicație. Una dintre problemele comune de care suferă dezvoltatorii care se străduiesc să scrie bine este dificultatea de a dedica timp optimizării performanței, îmbunătățirii mentenabilității sau altor lucruri care nu sunt incluse direct în planul de lucru. Există aproape întotdeauna o nevoie de afaceri pentru aceste îmbunătățiri. Cine nu vrea ca sistemul să funcționeze mai rapid, mai stabil și să fie mai ieftin de întreținut? Toate aceste beneficii pot fi evaluate și, pe baza acestei evaluări, sarcinile de îmbunătățire pot fi plasate în stoc, împreună cu oricare altele.


Deci, dacă doriți să optimizați performanța, dar trebuie să remediați un alt bug plictisitor, poate că pur și simplu nu știți cum să explicați beneficiile optimizării într-o limbă pe care proprietarul produsului o poate înțelege.

3. Lăsați codul mai curat decât era înainte

Aproape orice cod, cu excepția celui scris foarte recent, rămâne puțin în urma ideii actuale de frumusețe în domeniul stilului și arhitecturii. Când trebuie să schimbați codul ca parte a unei sarcini, este considerată o bună practică să faceți toate îmbunătățirile sigure posibile în zona afectată. Ce ar putea fi?

  • Aducerea modulelor la stilul actual.
  • Schimbarea numelor de variabile interne în altele mai ușor de înțeles.
  • Simplificați implementarea menținând comportamentul.
  • Refactoriri locale care nu introduc modificări la scară mare altor module.

Se așteaptă că aceste îmbunătățiri vor îmbunătăți codul, dar nu vor crește semnificativ costul dezvoltării sau testării.


Datorită acestui principiu, calitatea codului crește treptat în fundal, chiar și în acele locuri în care nu au fost planificate refactorizări separate. Mai mult, cu cât lucrăm mai des la o anumită parte a sistemului, cu atât este mai bun codul pentru această parte. Un contrast frumos cu proiectele în care dezvoltatorul petrece cel mai mult timp pe părțile cu cel mai prost cod.

4. Indiferent de ce se întâmplă, sistemul trebuie să rămână în stare de funcționare.

Unul dintre principiile de bază ale SCRUM spune că la sfârșitul fiecărui sprint sistemul ar trebui să ajungă într-o stare stabilă.


„Până la sfârșitul sprintului, incrementul ar trebui să fie gata, ceea ce înseamnă că îndeplinește criteriile de pregătire ale echipei Scrum și este gata de utilizare. Ar trebui să fie gata de utilizare, indiferent de decizia proprietarului produsului de a-l elibera sau de a-l întârzia.”

Orice lucrare de eliminare a datoriei tehnice se face cu respectarea acestui principiu.


Transformările mari sunt în mod necesar descompuse, astfel încât orice etapă individuală poate fi finalizată într-un singur sprint. De exemplu, am schimbat sistemul de construire în două etape (Angular 1.x: webpack târâtor, lurking grunt)


Lucrăm cu VCS după principii apropiate de gitflow clasic. Dezvoltarea se realizează în ramuri de caracteristici, testarea este efectuată acolo. De regulă, o astfel de ramură nu durează mai mult de un sprint de două săptămâni. O ramură care trăiește mai mult duce aproape întotdeauna la costuri suplimentare.


Experiența noastră confirmă clar acest tipar. De fiecare dată când nu am reușit să finalizam o refactorizare mare în două săptămâni, a fost o durere și o suferință. Și cu cât sarcina a fost mai lungă și cu cât ramura deschisă a trăit mai mult, cu atât munca mergea mai încet și cu atât existau mai multe probleme.


Necesitatea de a fi mereu la câțiva pași de o lansare stabilă creează una dintre cele mai dificile și mai interesante probleme de inginerie - găsirea descompunerii optime a planurilor strategice. Schimbările la scară largă pot fi împărțite în etape separate, independente. Este recomandabil să începeți să primiți beneficii cât mai curând posibil. Cu cât se realizează mai bine această defalcare a muncii, cu atât sunt mai mari șansele de finalizare a lucrării.

Cum arată procesul nostru

O dată pe lansare, facem o revizuire detaliată a restanțelor tehnice:

  • Închidem povești irelevante (relevanță pierdută, făcute ca parte a altceva, duplicate).
  • Actualizăm descrierea în care viziunea asupra problemei s-a schimbat.

Când poveștile de afaceri apar la orizont, se face o analiză tehnică și toate poveștile tehnice care ar ajuta la implementare sunt asociate cu povestea de afaceri.


În pregătirea pentru planificarea sprintului:

  • Verificăm conexiunile dintre poveștile tehnice și de afaceri.
  • Legăm toate erorile legate de povești tehnice care pot fi remediate ieftin în același loc.

Cum se formează partea tehnică a restanțelor

Când mi-am asumat rolul de lider al echipei, am întrebat fiecare dezvoltator și QA ce îmbunătățiri la produs doreau cel mai mult să facă. Majoritatea solicitărilor au fost legate de îmbunătățiri tehnice ale platformei și refactorizări. După cum a arătat experiența ulterioară, toate problemele tehnice cheie ale produsului au fost incluse în acest set de dorințe. Așadar, puteți folosi această practică pentru a construi rapid un stoc tehnic de la zero sau pentru a vă face o idee generală despre starea datoriei tehnice într-un proiect nou.


Completarea curentă a restanțelor cu sarcini tehnice are loc datorită practicilor descrise mai sus și nu necesită eforturi sau analize separate. În plus, noi idei pentru îmbunătățirea tehnică a produsului sunt adăugate la stocul de soluții. Acest lucru este realizat de orice membru al echipei care a venit cu o astfel de idee. Principalul lucru în această etapă este să nu pierdeți ideea. Clarificarea și determinarea priorității au loc ulterior, în timpul planificării lucrărilor.

concluzii

  • Datoria tehnică este inevitabilă.
  • Pentru majoritatea proiectelor, eliminarea datoriilor tehnice este o bună investiție de efort.
  • Dacă datoria tehnică nu este abordată, viteza de dezvoltare se va apropia treptat de zero.
  • Tentația de a arunca totul și de a scrie din nou vă poate ucide sau paraliza grav proiectul.
  • Beneficiile eliminării datoriilor tehnice ar trebui încadrate în termeni de beneficii de afaceri, altfel există riscul ca sarcinile pentru crearea de noi funcționalități să fie întotdeauna considerate mai importante.
  • Sarcinile de eliminare a datoriei tehnice merită gestionate. Astfel de sarcini nu sunt diferite de alte sarcini ale proiectului în ceea ce privește contabilitatea, planificarea și prioritizarea.
  • În mod regulat apar situații în care puteți reduce datoria tehnică și puteți rezolva o problemă de afaceri în același timp mai ieftin decât să o faceți separat. Aceste oportunități trebuie folosite.
  • Convențiile de stil de cod și procesele de revizuire atent și actualizate în timp util ajută la încetinirea apariției unor noi datorii tehnice.
  • Iterațiile scurte sunt la fel de utile pentru refactorizări, precum sunt pentru dezvoltarea de noi funcționalități.
  • Echipa știe de obicei unde este datoria tehnică în proiect și cât de proastă este. Merită să folosiți aceste cunoștințe atunci când vă faceți o idee despre datoria tehnică a proiectului.

În răspunsul meu voi atinge nu numai Marile Case, ci și alte case despre care am putut obține informații.

1.Starkey - "Vine iarna„. Înseamnă că pacea și securitatea sunt temporare și iluzorii; trebuie să fii mereu pregătit pentru dezastre și războaie pentru a face față pericolului complet înarmat. În Westeros, iarna nu este doar un anotimp care durează ani de zile, ci și un simbol al încercărilor dificile. Și, de fapt, acest motto privește nu numai Casa Stark, ci întreaga țară.

2. Lannisters- Casa Lannister pare să aibă două motto-uri, unul confirmând o stemă formidabilă -" Ascultă-mi vuietul!", al doilea, echivalent cu o zicală, dar care sună un ordin de mărime mai des decât primul - " Lannisterii își plătesc întotdeauna datoriile". Primul motto poate fi atribuit direct stemei. Stema Lannister descrie leu rampant- „un leu care răcnește”, iar motto-ul „Ascultă-mi vuietul” îl completează direct, este, de asemenea, o dovadă că leul este regele fiarelor, iar Lannisterii au o poziție înaltă în societate. Zicala „Un Lannister își plătește întotdeauna datoriile” este asociată în primul rând cu Banca de Fier din Braavos „Banca de Fier va primi întotdeauna ceea ce trebuie”. În al doilea rând, „Un Lannister își plătește întotdeauna datoriile” înseamnă că Lannisterii nu-i uită niciodată pe cei care i-au ajutat și că Lannisterii nu iartă niciodată greșelile care le-au fost făcute.

3. Baratheon - "Suntem furiosi". a aparținut inițial Durrandonilor din Storm's End. Orys Baratheon (fratele nelegitim al lui Aegon I Cuceritorul), după ce l-a ucis pe Argilac cel Arogant, ultimul Domn al Țărilor Furtunii, și-a adoptat motto-ul. Dar motto-ul a fost tradus prea literal. Dă o traducere logică a motto-ului" Furia este elementul nostru", cu o explicație a semnificației sale" Furia este elementul nostru, ceea ce înseamnă: când ne enervezi, arunci peștele în mare, unde se simte grozav.„Adică, pentru Baratheon, o manifestare violentă de emoții în detrimentul rațiunii reci nu este un viciu.

4. Greyjoy - "Noi nu semănăm"Greyjoy sunt în mare parte pirați. Teritoriul pământurilor lor este situat pe stânci goale și nisip. Motto-ul acestei case este un mesaj direct că Greyjoy nu lucrează pe pământ (care chiar nu există). Ei nu seamănă. orice și nu cresc, ei jefuiesc pe cei care au recoltă și pradă, pentru că nu au și nu pot avea al lor.

5. Targaryen - "Foc si sange„. Motto-ul Targaryen poate fi interpretat în două moduri. Primul - Aegon Cuceritorul și cele două surori ale sale, pe trei dragoni, au subjugat Westerosul, care se numește „cu el și cu sabia”. A doua opțiune - (menționată mai sus apus de soare) - " Targaryeni sunt născuți de dragoni, au sângele anticului Valyria și dragoni, precum și un bonus de imunitate la foc și dragoni îmblânziți. Când Targaryen spun Foc și Sânge, le amintesc celor care au uitat brusc de asta."

6. Arryns - "Înalt ca onoare„Pe de o parte, Casa Arryn, urmând exemplul lui Jon Arryn, s-a preocupat de păstrarea onoarei. Jon nu putea fi intimidat sau mituit. Și în ținuturile Westeros era imposibil să găsești pe cineva căruia îi pasă mai mult de păstrarea onoarei decât Dar după moartea lui Jon, probabil că o altă opțiune este mai aplicabilă - aroganța aristocratică, disprețul pentru cei cu statut inferior, ei spun, „de unde ești de la noi”.

7. Tarly - "Primul în luptă„Casa Tarly a dat naștere multor mari războinici și generali remarcabili, așa cum confirmă acest motto.

8. Tully - "Familie, datorie, onoare„House Tully este loială înainte de toate legăturilor sale de familie. Datoria și onoarea vin după ei, dar familia este pe primul loc. Casa Tully l-a susținut pe Rob Stark în Războiul celor Cinci Regi, pentru care au plătit.

9. Martells - "Neclintit, neînduplecat, neînduplecat". Un model de mândrie și inflexibilitate. Martell-ii sunt singura casă pe care Targaryen nu au putut-o lua cu forța. Și din comportamentul personajelor acestei case este destul de evident că sunt încăpățânați și de neclintit. Nu au nevoie de legile Domnilor, aprobarea Regilor, sunt pe cont propriu, dar arată clar că nu sunt gata să renunțe.

10. Tyrell - "Crescând, devenim mai puternici". Motto-ul casei Tyrell a fost confirmat de armata lor, al cărei număr nu putea fi comparat cu nicio armată din Westeros. Tyrell-ii aveau și o „pernă” sub forma bogăției pe care o acumulaseră. Având în vedere că haina de brațe ale acestei case înfățișează un trandafir, o paralelă poate fi, de asemenea, trasată cu el De la un mugur mic la un tuf uriaș de trandafiri.Așa că membrii casei Tyrell, acumulând treptat forță, și-au dezvoltat și întărit pozițiile.Cu toate acestea, așa cum însăși Olenna a spus, nu sunt deloc războinici.

11. Șurub pe -"Lamele noastre sunt ascuțite". Acest motto servește mai degrabă ca un avertisment pentru inamicii (și nu numai) familiei Bolton. Reprezentanții acestei case au o reputație sumbră; în cărți chiar purtau mantii din piele umană și împodobeau cu ea pereții castelelor lor. : „Un bărbat gol nu are secrete, dar un bărbat jupuit și cu atât mai mult.” „Lamele noastre sunt ascuțite” – se pare că poate însemna și lame pentru jupuirea cărnii.

12. Mormont - "Aici stam". Motto-ul, care, potrivit Sunsetsolitude, este, de asemenea, tradus incorect în rusă." Aici stăm - poate însemna „Iată pământurile noastre”, care la rândul său înseamnă „O insulă mică, dar mândră, care nu deranjează pe nimeni, dar se poate defini singură. Aici sunt pământurile noastre, amintește-ți asta când vei veni aici, noi va avertizat.” Sau poate fi tradus ca „Pe asta stăm” - ceea ce ar fi un indiciu direct al forței încăpățânării mormontilor."

13. Frey - "Stăm umăr la umăr„Soții Frey prețuiau legăturile de familie și inviolabilitatea acestui cuvânt, ceea ce reflecta acest motto. De acolo, Walder Frey a avut o ranchiune de nespus față de Rob Stark, care și-a încălcat promisiunea de a se căsători cu fiica sa, ceea ce a dus la consecințe triste.

„Un Lannister își plătește întotdeauna datoriile”. © FFG ( Jason A. Engle)

„Lannisterii își plătesc întotdeauna datoriile”(De asemenea: „Un Lannister își plătește întotdeauna datoriile” ascultă)) este o zicală populară din cele șapte regate despre Casa Lannister și o expresie preferată a lui Tyrion Lannister. Nu este mai puțin faimos decât motto-ul „oficial” al casei, „Ascultă-mă rugit!” Această expresie are un dublu sens. Pe de o parte, înseamnă că familia Lannister, ca cea mai bogată casă din stat, sunt întotdeauna gata să plătească facturile și să mulțumească celor care i-au ajutat sau să promită recompense în viitor - poți conta oricând pe generozitatea și angajamentul „lei”. Dar acest motto are și un al doilea sens, amenințător: Lannisterii nu uită insultele aduse lor și cu siguranță se vor răzbuna pe infractori.

În gura lui Cersei Lannister, zicala a sunat într-un discurs îndreptat împotriva lui Tyrion însuși - Cersei și-a acuzat fratele de intrigi împotriva ei și a lui Joffrey și a încercat să o șantajeze pe Alaya capturată. Ulterior, regăsindu-se în fruntea statului, Cersei a folosit aceleași cuvinte pentru a-și justifica decizia de a nu mai plăti datorii publice către Banca de Fier din Braavos - Lannisterii își plătesc mereu datoriile, iar această datorie va fi plătită mai devreme sau mai târziu. Ea a menționat mai târziu această zicală într-un dialog cu Balman Birch și Falisa Stokeworth, promițându-le o recompensă pentru ajutorul lor, apoi i-a trimis pe Tyroshi care a încercat să o înșele la călău cu cuvintele „Lannisters își plătesc datoriile și tu vei plăti. de asemenea."

Tywin Lannister a menționat această zicală într-o conversație cu Tyrion, justificând necesitatea de a-i da Harrenhal lui Petyr Baelish, deoarece el însuși și-a dorit asta. Tyrion însuși a repetat imediat cuvintele despre datorii, cerând o recompensă pentru serviciile sale ca Hand. Shae repetă zicala, amintindu-i lui Tyrion de promisiunea lui de a o pune înapoi în casa orașului. După ce a aflat despre dezertarea Westerlings la Robb Stark, Tyrion s-a gândit în sine că Tywin va pedepsi cu siguranță trădătorii și și-a amintit vorba.

Jaime Lannister i-a amintit lui Urswick de ea, încercând să-l seducă cu bogăție, iar mai târziu, pierzându-și mâna, el și-a repetat zicala, alimentându-și setea de răzbunare și dorința de a trăi. El i-a spus lui Brienne din Tarth că a salvat-o de la viol în semn de recunoștință pentru scufundarea galerei lui Robin Rieger la începutul călătoriei lor, amintindu-și din nou vorba. Mai târziu a repetat aceste cuvinte într-o conversație cu Varys, explicându-și astfel dorința de a-l elibera pe Tyrion. După ce l-a scos pe Edmure Tully de pe schela de la zidurile Riverrun, Jaime s-a gândit în sinea lui: „Lannisterii își plătesc datoriile, iar tu ești singura monedă care mi-a mai rămas”.

Edmure Tully însuși și-a amintit zicala când a aflat despre uciderea lui Rickard Karstark a lui Willem Lannister și Theon Frey. Roose Bolton, vorbind despre intenția sa de a părăsi Harrenhal și de a lăsa în seama lui Vargo Howth, „Lannisterii nu sunt singurii care își plătesc datoriile”. Jaime a repetat zicala când și-a luat rămas bun de la Băieții curajoși când a părăsit castelul, dând de înțeles că se va răzbuna pe ei, iar apoi, întorcându-se la castel pentru Brienne, i-a adresat aceleași cuvinte lui Vargo Haught, spunând că va primi. o răscumpărare atât pentru Jaime, cât și pentru Brienne

Practici tehnologice de management al datoriilor într-o singură echipă


În urmă cu aproximativ un an, echipa noastră a trecut de la o fază de creștere rapidă a caracteristicilor la o dezvoltare mai fluidă, cu accent pe îmbunătățirea calității. În acest moment, produsele noastre au acumulat o cantitate considerabilă de soluții suboptime, cod urat și biblioteci învechite. Trebuia făcut ceva în legătură cu toate acestea.


Până în prezent, am reușit să construim un proces care face ca lupta împotriva datoriilor tehnice să fie previzibilă, nedureroasă și inevitabilă.


Ce am obtinut ca rezultat:

  • Echipa este fericită. Retrospectiva de lansare include în mod regulat puncte pozitive despre îmbunătățirea tehnologiei și reducerea datoriei tehnice.
  • Pentru mai multe lansări trimestriale la rând, am reușit să creștem funcționalitatea fără a crește numărul de linii de cod din proiect. Eliminarea codului inutil și simplificarea a ceea ce era necesar a redus dimensiunea bazei de cod pentru funcționalitatea existentă. Și această reducere a coincis în mare măsură cu noul cod care implementează noua funcționalitate.
  • În timpul refactorizărilor și modernizărilor, produsul este întotdeauna în stare de funcționare. La fiecare două săptămâni lansăm o versiune intermediară complet funcțională.

Să vă spun cum am reușit acest lucru.

Ce este datoria tehnică

Definiția mea de lucru a datoriei tehnice este cantitatea de muncă care trebuie făcută pentru ca un proiect să îndeplinească viziunea echipei despre ceea ce este grozav. Rețineți că datoria tehnică poate apărea nu numai din cauza utilizării liberale a cârjelor în dezvoltare, ci și din cauza schimbării ideilor despre frumusețe. De exemplu, practicile comune din industrie s-au schimbat. Sau dezvoltatorii s-au îndrăgostit de OOP și s-au îndrăgostit de programarea funcțională. Sau cadrul cândva la modă nu mai este un tort și a devenit dificil să găsești specialiști care ar dori să scrie pe el.


Cu toate acestea, principala cauză a datoriei tehnice este entropia în toată diversitatea ei. Teste unitare dezactivate, comentarii învechite care au pierdut contactul cu codul, decizii arhitecturale nereușite, implementare de caracteristici pe care nimeni nu le mai folosește, o bază pentru un viitor care nu a venit și multe, multe altele.


Rezultă că apariția datoriilor tehnice este inevitabilă în orice proiect de lungă durată.

Când datoria tehnică nu este o problemă

De ce datoria tehnică este proastă? Mărește costul dezvoltării ulterioare datorită mai multor factori:

  • Viteza de implementare a noilor funcționalități este redusă.
  • Probabilitatea regresiilor la corectarea defectelor crește.
  • Procesul de dezvoltare devine mai puțin previzibil și, prin urmare, mai puțin gestionabil.
  • Procesul de introducere a unui nou dezvoltator în proiect se prelungește.

Această pierdere este uneori numită „dobândă pentru datoria tehnică”


Există situații în care aceste pierderi sunt mai ieftine decât eliminarea datoriei tehnice:

  • Sfârșitul vieții proiectului este aproape. Rețineți, acesta nu este sfârșitul adăugării de funcționalități, ci momentul în care puteți înceta să pierdeți eforturile programatorilor și pe suport. În această categorie sunt incluse și prototipuri unice, demonstrații unice pentru expoziții etc.
  • Valoarea timpului de dezvoltare acum este mult mai mare decât se aștepta în viitor. Remedieri urgente la un termen limită fix, startup-uri care rămân fără bani din următoarea rundă de finanțare etc. În astfel de cazuri, repararea datoriilor tehnice poate fi amânată până când căldura momentului se răcește. Sunt proiecte care nu ies dintr-o stare de urgență, dar sfaturile din acest articol tot nu le vor ajuta.

Ce să faci cu datoria tehnică? Abordări eșuate

Abordarea nr. 1. „Nu avem timp, eliberarea trebuie depusă ieri”

Dorința de a respecta termenul de mâine cu orice preț, în detrimentul vitezei de dezvoltare poimâine.


Uneori, o structură prefabricată din cârje este o alegere corectă în mod obiectiv. În practica mea, acest lucru a fost exprimat cel mai clar când am făcut versiuni demo pentru expoziții. Data evenimentului este strict fixată; dacă nu ați ajuns la timp pentru o expoziție importantă, următoarea încercare va fi într-un an. În acest caz, puteți afișa produsul „din mâinile tale”, evitând cu atenție toate erorile. Ca inginer, este neplăcut pentru mine să fac astfel de proiecte, dar cârjele din ele sunt justificate.


Când faci un produs care va dura mult timp, totul este diferit. Respectarea termenului limită din cauza soluțiilor tehnice dubioase este o plăcere costisitoare. Costul total este:

  1. de la punerea în aplicare a cârjei în sine,
  2. de la înlocuirea sa ulterioară cu o soluție cu drepturi depline,
  3. din suferința de a avea o cârjă între punctele anterioare.

Al doilea punct este foarte ușor de subestimat și există riscul să nu ne gândim la al treilea, cel mai scump deloc.


Când întâlnești un lider tehnic cu un ochi tremurător la o conferință, se poate dovedi că a fost coșmarul depanării la nesfârșit a unui design făcut din cârje care l-a adus în această stare.


Abordarea nr. 2. „Da, aici trebuie să aruncăm totul și să scriem din nou”

Cu cât situația datoriei tehnice este mai proastă, cu atât mai puternică este tentația de a îngropa întregul cod al proiectului și de a scrie totul din nou. Aceasta este una dintre greșelile clasice care poate ucide întregul proiect.


Subiectul este atât de bine tratat în celebrul articol al lui Joel Spolsky încât nu văd niciun rost să-mi prezint propriile argumente.

Abordarea nr. 3. „Vom refactoriza noaptea și în weekend, astfel încât managerul să nu afle.”

Argumentarea necesității eliminării datoriilor tehnice în ceea ce privește beneficiile de afaceri nu este întotdeauna ușoară. Echipa de dezvoltare poate fi tentată să ocolească marginile aspre și să înceapă o refactorizare majoră pe loc. Acest lucru se poate face în timpul orelor nelucrătoare, în pauze între alte sarcini sau „la coada” altor sarcini prin umflarea estimărilor.


Ce e rău în asta? Oh, o grămadă de lucruri:

  • Transparența redusă subminează încrederea dintre management și echipă. Adesea, încercările ulterioare de a corecta situația prin impunerea disciplinei și strângerea șuruburilor vor duce la o deteriorare suplimentară a muncii în echipă.
  • O situație înrădăcinată în care prioritățile echipei și ale managementului sunt conflictuale provoacă demotivare de ambele părți.
  • Fructele refactorizării sunt incluse în produs în moduri imprevizibile și provoacă erori de regresie acolo unde nu sunt așteptate. În echipele conștiente, acest lucru duce la o încărcare bruscă și neplanificată a QA. În inconștient, intră în producție și se defectează acolo.

După ce echipa folosește această rețetă, ochii conducerii încep să treacă.

Principiile noastre

1. Adăugați sarcini tehnice la restanța generală

Există o serie de modele în viața sarcinilor din proiecte:

  • O sarcină care nu este în așteptare are mai puține șanse de a intra în muncă.
  • O sarcină fără o formulare clară are mai puține șanse de a intra în muncă.
  • O sarcină care nu poate fi estimată cu un grad ridicat de încredere are mai puține șanse de a intra în muncă.
  • O sarcină mare va aștepta mai mult în coadă decât una mică.

Maxim Dorofeev vorbește foarte bine despre aceste lucruri în „Tehnica lui „Empty Inbox Technique”


Pentru a preveni acumularea datoriilor tehnice, lucrările de eliminare ar trebui finalizate ținând cont de principiile enumerate mai sus.


Toate sarcinile, cu excepția celor mai mici, sunt listate în stoc. Astfel, ei au șansa de a se face nu numai în timpul liber, ci și ca parte a muncii planificate. În plus, astfel de sarcini sunt mai greu de pierdut complet din vedere - restanța este analizată mai des și mai atent decât la TODO din cod, bucăți de hârtie pe monitor, pagini wiki abandonate, șervețele pătate de ceai cu diagrame și altele. surse de informare.

  • Dacă în cod există o TODO non-trivială, aceasta conține un link către sarcina din backlog. Verificăm conformitatea cu acest principiu la revizuirea codului și nu acceptăm TODO complexe fără referințe.

    S-ar putea să existe o dramă în spatele comentariului.

    Odată, lângă un astfel de TODO scria: „Crânja. Product Ownerul m-a pus să o fac. Îndepărtați cât mai curând posibil.”

  • Când un dezvoltator își dă seama că un loc necesită refactorizare, el creează o problemă în restanță.
  • Când un dezvoltator are dorința de a îmbunătăți platforma, el creează o sarcină în backlog.
  • Planurile arhitecturale pe termen lung sunt puse în așteptare sub formă de sarcini separate, de îndată ce există suficientă certitudine cu privire la cel puțin primii pași.

Atâta timp cât astfel de modificări rămân ieftine în ceea ce privește costurile de dezvoltare și cantitatea de testare necesară, ne putem îmbunătăți treptat baza de coduri fără a întrerupe obiectivele de afaceri sau a introduce riscuri suplimentare.

2. Planificați poveștile tehnice pe baza priorităților de afaceri

Dacă un copac a căzut în pădure, dar nimeni nu l-a auzit, a existat un sunet? Dacă există cod prost într-un proiect, dar acel modul nu va trebui niciodată schimbat, există datorii tehnice?


Cred că atunci când un programator consideră că este neplăcut să se uite la un modul vechi, aceasta în sine nu este o problemă foarte mare. Mult mai rău este ceea ce se întâmplă atunci când trebuie să adăugați o nouă funcționalitate la acest modul sau să o extindeți pe cea veche. În comparație cu efectuarea de modificări la codul bine scris, astfel de sarcini sunt mai probabil (și mai probabil să depășească estimarea inițială) și conțin mai multe erori. Uneori mult mai mult. Pentru a ne proteja de aceste tipuri de probleme, încercăm să programăm refactorizările astfel încât acestea să fie făcute înainte de a scrie noi funcționalități în același loc.


Dacă modificările de funcționalitate și refactorizările par mici, se pot face împreună. Dimensiunea selectată empiric a sarcinii pentru care această abordare va fi optimă este de 3 zile de lucru pentru un dezvoltator sau mai puțin. Când este clar că există mai multă muncă, aceasta este împărțită în refactorizare, menținând în același timp comportamentul actual și implementând noi funcționalități.


Astfel, ordinea de lucru pentru eliminarea datoriilor tehnice este determinată de ordinea sarcinilor de afaceri din restanță.


Principiul „priorităților de afaceri” are o altă aplicație. Una dintre problemele comune de care suferă dezvoltatorii care se străduiesc să scrie bine este dificultatea de a dedica timp optimizării performanței, îmbunătățirii mentenabilității sau altor lucruri care nu sunt incluse direct în planul de lucru. Există aproape întotdeauna o nevoie de afaceri pentru aceste îmbunătățiri. Cine nu vrea ca sistemul să funcționeze mai rapid, mai stabil și să fie mai ieftin de întreținut? Toate aceste beneficii pot fi evaluate și, pe baza acestei evaluări, sarcinile de îmbunătățire pot fi plasate în stoc, împreună cu oricare altele.


Deci, dacă doriți să optimizați performanța, dar trebuie să remediați un alt bug plictisitor, poate că pur și simplu nu știți cum să explicați beneficiile optimizării într-o limbă pe care proprietarul produsului o poate înțelege.

3. Lăsați codul mai curat decât era înainte

Aproape orice cod, cu excepția celui scris foarte recent, rămâne puțin în urma ideii actuale de frumusețe în domeniul stilului și arhitecturii. Când trebuie să schimbați codul ca parte a unei sarcini, este considerată o bună practică să faceți toate îmbunătățirile sigure posibile în zona afectată. Ce ar putea fi?

  • Aducerea modulelor la stilul actual.
  • Schimbarea numelor de variabile interne în altele mai ușor de înțeles.
  • Simplificați implementarea menținând comportamentul.
  • Refactoriri locale care nu introduc modificări la scară mare altor module.

Se așteaptă că aceste îmbunătățiri vor îmbunătăți codul, dar nu vor crește semnificativ costul dezvoltării sau testării.


Datorită acestui principiu, calitatea codului crește treptat în fundal, chiar și în acele locuri în care nu au fost planificate refactorizări separate. Mai mult, cu cât lucrăm mai des la o anumită parte a sistemului, cu atât este mai bun codul pentru această parte. Un contrast frumos cu proiectele în care dezvoltatorul petrece cel mai mult timp pe părțile cu cel mai prost cod.

4. Indiferent de ce se întâmplă, sistemul trebuie să rămână în stare de funcționare.

Unul dintre principiile de bază ale SCRUM spune că la sfârșitul fiecărui sprint sistemul ar trebui să ajungă într-o stare stabilă.


„Până la sfârșitul sprintului, incrementul ar trebui să fie gata, ceea ce înseamnă că îndeplinește criteriile de pregătire ale echipei Scrum și este gata de utilizare. Ar trebui să fie gata de utilizare, indiferent de decizia proprietarului produsului de a-l elibera sau de a-l întârzia.”

Orice lucrare de eliminare a datoriei tehnice se face cu respectarea acestui principiu.


Transformările mari sunt în mod necesar descompuse, astfel încât orice etapă individuală poate fi finalizată într-un singur sprint. De exemplu, am schimbat sistemul de asamblare în două etape ()


Lucrăm cu VCS după principii apropiate de gitflow clasic. Dezvoltarea se realizează în ramuri de caracteristici, testarea este efectuată acolo. De regulă, o astfel de ramură nu durează mai mult de un sprint de două săptămâni. O ramură care trăiește mai mult duce aproape întotdeauna la costuri suplimentare.


Experiența noastră confirmă clar acest tipar. De fiecare dată când nu am reușit să finalizam o refactorizare mare în două săptămâni, a fost o durere și o suferință. Și cu cât sarcina a fost mai lungă și cu cât ramura deschisă a trăit mai mult, cu atât munca mergea mai încet și cu atât existau mai multe probleme.


Necesitatea de a fi mereu la câțiva pași de o lansare stabilă creează una dintre cele mai dificile și mai interesante probleme de inginerie - găsirea descompunerii optime a planurilor strategice. Schimbările la scară largă pot fi împărțite în etape separate, independente. Este recomandabil să începeți să primiți beneficii cât mai curând posibil. Cu cât se realizează mai bine această defalcare a muncii, cu atât sunt mai mari șansele de finalizare a lucrării.

Cum arată procesul nostru

O dată pe lansare, facem o revizuire detaliată a restanțelor tehnice:

  • Închidem povești irelevante (relevanță pierdută, făcute ca parte a altceva, duplicate).
  • Actualizăm descrierea în care viziunea asupra problemei s-a schimbat.

Când poveștile de afaceri apar la orizont, se face o analiză tehnică și toate poveștile tehnice care ar ajuta la implementare sunt asociate cu povestea de afaceri.


În pregătirea pentru planificarea sprintului:

  • Verificăm conexiunile dintre poveștile tehnice și de afaceri.
  • Legăm toate erorile legate de povești tehnice care pot fi remediate ieftin în același loc.

Cum se formează partea tehnică a restanțelor

Când mi-am asumat rolul de lider al echipei, am întrebat fiecare dezvoltator și QA ce îmbunătățiri la produs doreau cel mai mult să facă. Majoritatea solicitărilor au fost legate de îmbunătățiri tehnice ale platformei și refactorizări. După cum a arătat experiența ulterioară, toate problemele tehnice cheie ale produsului au fost incluse în acest set de dorințe. Așadar, puteți folosi această practică pentru a construi rapid un stoc tehnic de la zero sau pentru a vă face o idee generală despre starea datoriei tehnice într-un proiect nou.


Completarea curentă a restanțelor cu sarcini tehnice are loc datorită practicilor descrise mai sus și nu necesită eforturi sau analize separate. În plus, noi idei pentru îmbunătățirea tehnică a produsului sunt adăugate la stocul de soluții. Acest lucru este realizat de orice membru al echipei care a venit cu o astfel de idee. Principalul lucru în această etapă este să nu pierdeți ideea. Clarificarea și determinarea priorității au loc ulterior, în timpul planificării lucrărilor.

concluzii

  • Datoria tehnică este inevitabilă.
  • Pentru majoritatea proiectelor, eliminarea datoriilor tehnice este o bună investiție de efort.
  • Dacă datoria tehnică nu este abordată, viteza de dezvoltare se va apropia treptat de zero.
  • Tentația de a arunca totul și de a scrie din nou vă poate ucide sau paraliza grav proiectul.
  • Beneficiile eliminării datoriilor tehnice ar trebui încadrate în termeni de beneficii de afaceri, altfel există riscul ca sarcinile pentru crearea de noi funcționalități să fie întotdeauna considerate mai importante.
  • Sarcinile de eliminare a datoriei tehnice merită gestionate. Astfel de sarcini nu sunt diferite de alte sarcini ale proiectului în ceea ce privește contabilitatea, planificarea și prioritizarea.
  • În mod regulat apar situații în care puteți reduce datoria tehnică și puteți rezolva o problemă de afaceri în același timp mai ieftin decât să o faceți separat. Aceste oportunități trebuie folosite.
  • Convențiile de stil de cod și procesele de revizuire atent și actualizate în timp util ajută la încetinirea apariției unor noi datorii tehnice.
  • Iterațiile scurte sunt la fel de utile pentru refactorizări, precum sunt pentru dezvoltarea de noi funcționalități.
  • Echipa știe de obicei unde este datoria tehnică în proiect și cât de proastă este. Merită să folosiți aceste cunoștințe atunci când vă faceți o idee despre datoria tehnică a proiectului.

CATEGORII

ARTICOLE POPULARE

2024 „kingad.ru” - examinarea cu ultrasunete a organelor umane