I Lannister pagano sempre i loro debiti. Qual è il motto dei Lannister? Yuri Boldyrev diffama il meschino blogger sub-Cremlino Rogers

Pratiche tecnologiche di gestione del debito in un unico team


Circa un anno fa, il nostro team è passato da una fase di rapida crescita delle funzionalità a uno sviluppo più fluido con particolare attenzione al miglioramento della qualità. A questo punto, i nostri prodotti hanno accumulato una notevole quantità di soluzioni non ottimali, codice brutto e librerie obsolete. Bisognava fare qualcosa riguardo a tutto questo.


Ad oggi siamo riusciti a costruire un processo che rende la lotta al debito tecnico prevedibile, indolore e inevitabile.


Cosa abbiamo ottenuto come risultato:

  • La squadra è felice. La retrospettiva del rilascio include regolarmente punti positivi sul miglioramento della tecnologia e sulla riduzione del debito tecnico.
  • Per diversi rilasci trimestrali consecutivi, siamo stati in grado di aumentare la funzionalità senza aumentare il numero di righe di codice nel progetto. La rimozione del codice non necessario e la semplificazione di ciò che era necessario hanno ridotto le dimensioni della base di codice per le funzionalità esistenti. E questa riduzione ha più o meno coinciso in scala con il nuovo codice che implementa la nuova funzionalità.
  • Durante i refactoring e gli aggiornamenti, il prodotto è sempre funzionante. Ogni due settimane rilasciamo una versione provvisoria completamente funzionante.

Lasciate che vi spieghi come abbiamo raggiunto questo obiettivo.

Cos’è il debito tecnico

La mia definizione operativa di debito tecnico è la quantità di lavoro che deve essere svolta per far sì che un progetto soddisfi la visione di ciò che è eccezionale del team. Si noti che il debito tecnico può sorgere non solo a causa dell'uso liberale delle stampelle nello sviluppo, ma anche a causa del cambiamento delle idee sulla bellezza. Ad esempio, le pratiche comuni del settore sono cambiate. Oppure gli sviluppatori si sono innamorati dell'OOP e si sono innamorati della programmazione funzionale. Oppure il quadro un tempo di moda non è più una torta ed è diventato difficile trovare specialisti che vorrebbero scriverci sopra.


Tuttavia, la causa principale del debito tecnico è l’entropia in tutta la sua diversità. Unit test disabilitati, commenti obsoleti che hanno perso il contatto con il codice, decisioni architetturali infruttuose, implementazione di funzionalità che nessuno utilizza più, basi per un futuro che non è arrivato e molto, molto altro ancora.


Ne consegue che la comparsa del debito tecnico è inevitabile in qualsiasi progetto di lunga durata.

Quando il debito tecnico non è un problema

Perché il debito tecnico è negativo? Aumenta il costo dell’ulteriore sviluppo a causa di una serie di fattori:

  • La velocità di implementazione delle nuove funzionalità è ridotta.
  • Aumenta la probabilità di regressioni durante la correzione dei difetti.
  • Il processo di sviluppo diventa meno prevedibile e quindi meno gestibile.
  • Il processo di introduzione di un nuovo sviluppatore nel progetto si sta allungando.

Questa perdita è talvolta chiamata "interesse sul debito tecnico"


Ci sono situazioni in cui queste perdite sono più economiche che eliminare il debito tecnico:

  • La fine della vita del progetto è vicina. Tieni presente che questa non è la fine dell'aggiunta di funzionalità, ma il momento in cui puoi smettere di sprecare gli sforzi dei programmatori anche per il supporto. Questa categoria comprende anche prototipi unici, dimostrazioni uniche per mostre, ecc.
  • Il valore del tempo di sviluppo attuale è molto più elevato di quanto previsto in futuro. Correzioni urgenti a una scadenza fissa, startup che stanno finendo i soldi dal prossimo round di finanziamento, ecc. In questi casi, la riparazione del debito tecnico può essere ritardata fino a quando la foga del momento non si sarà calmata. Ci sono progetti che non escono dallo stato di emergenza, ma i consigli di questo articolo non li aiuteranno comunque.

Cosa fare con il debito tecnico? Approcci falliti

Approccio n.1. “Non abbiamo tempo, la liberatoria deve essere presentata ieri”

Il desiderio di rispettare la scadenza di domani ad ogni costo, a scapito della velocità di sviluppo di dopodomani.


A volte una struttura prefabbricata realizzata con le stampelle è una scelta oggettivamente corretta. Nella mia pratica, questo è stato espresso più chiaramente quando si realizzavano versioni demo per le mostre. La data dell’evento è fissata rigorosamente; se non sei arrivato in tempo per una mostra importante, il prossimo tentativo sarà tra un anno. In questo caso puoi mostrare il prodotto “fuori dalle tue mani”, evitando attentamente ogni bug. Come ingegnere, è spiacevole per me realizzare tali progetti, ma le stampelle in essi contenute sono giustificate.


Quando realizzi un prodotto che durerà a lungo, tutto è diverso. Rispettare la scadenza a causa di soluzioni tecniche dubbie è un piacere costoso. Il costo totale è:

  1. dalla realizzazione della stampella stessa,
  2. dalla sua successiva sostituzione con una soluzione a tutti gli effetti,
  3. dalla sofferenza di avere una stampella tra i punti precedenti.

Il secondo punto è molto facile da sottovalutare, e c’è il rischio di non pensare al terzo, quello più costoso in assoluto.


Quando incontri un responsabile tecnologico con gli occhi tremanti a una conferenza, potrebbe scoprire che è stato l'incubo di eseguire il debug infinito di un progetto fatto con le stampelle a portarlo in questo stato.


Approccio n. 2. “Sì, qui bisogna buttare tutto e riscriverlo”

Quanto peggiore è la situazione debitoria tecnica, tanto più forte è la tentazione di seppellire l'intero codice del progetto e riscrivere tutto da capo. Questo è uno dei classici errori che possono uccidere l’intero progetto.


L'argomento è così ben trattato nel famoso articolo di Joel Spolsky che non vedo il motivo di presentare le mie argomentazioni.

Approccio n. 3. "Effettueremo il refactoring di notte e nei fine settimana in modo che il manager non lo scopra."

Sostenere la necessità di eliminare il debito tecnico in termini di vantaggi aziendali non è sempre facile. Il team di sviluppo potrebbe essere tentato di aggirare gli spigoli e avviare un importante refactoring sul posto. Questo può essere fatto durante le ore non lavorative, nelle pause tra altre attività o “in coda” ad altre attività gonfiando le stime.


Cosa c'è di male? Oh, un sacco di cose:

  • La ridotta trasparenza mina la fiducia tra il management e il team. Spesso i tentativi successivi di correggere la situazione imponendo disciplina e stringendo le viti porteranno a un ulteriore deterioramento del lavoro di squadra.
  • Una situazione radicata in cui le priorità del team e del management sono in conflitto provoca demotivazione da entrambe le parti.
  • I frutti del refactoring vengono inclusi nel prodotto in modi imprevedibili e causano bug di regressione dove non sono previsti. Nei team consapevoli, ciò porta a un carico improvviso e non pianificato sul QA. Nell'inconscio entra in produzione e lì si rompe.

Dopo che il team ha utilizzato questa ricetta, gli occhi del management iniziano a tremare.

I nostri principi

1. Aggiungere compiti tecnici all'arretrato generale

Esistono numerosi modelli nella vita delle attività nei progetti:

  • Un compito che non è in arretrato ha meno possibilità di entrare nel lavoro.
  • Un compito senza una formulazione chiara ha meno possibilità di entrare nel lavoro.
  • Un compito che non può essere stimato con un alto grado di sicurezza ha meno possibilità di entrare nel lavoro.
  • Un'attività di grandi dimensioni attenderà più a lungo in coda rispetto a una piccola.

Maxim Dorofeev parla molto bene di queste cose nella sua “Tecnica della casella di posta vuota”


Per evitare l'accumulo del debito tecnico, i lavori per la sua eliminazione dovrebbero essere completati tenendo conto dei principi sopra elencati.


Tutte le attività, tranne quelle più piccole, sono elencate nel backlog. In questo modo hanno la possibilità di essere svolti non solo nel tempo libero, ma anche come parte del lavoro pianificato. Inoltre, tali compiti sono più difficili da perdere completamente di vista: il backlog viene esaminato più spesso e più da vicino rispetto alle TODO nel codice, pezzi di carta sul monitor, pagine wiki abbandonate, tovaglioli macchiati di tè con diagrammi e altro fonti di informazione.

  • Se nel codice è presente una TODO non banale, contiene un collegamento all'attività nel backlog. Verifichiamo il rispetto di questo principio in fase di revisione del codice e non accettiamo TODO complessi senza riferimenti.

    Potrebbe esserci un dramma dietro il commento.

    Una volta, accanto a un TODO del genere c'era scritto: “Stampella. Il Product Owner mi ha costretto a farlo. Toglietela il più presto possibile."

  • Quando uno sviluppatore si rende conto che qualche posto richiede il refactoring, crea un problema nel backlog.
  • Quando uno sviluppatore desidera migliorare la piattaforma, crea un'attività nel backlog.
  • I piani architettonici a lungo termine vengono inseriti nell'arretrato sotto forma di compiti separati non appena si ha sufficiente certezza almeno sui primi passi.

Finché tali modifiche rimangono poco costose in termini di costi di sviluppo e quantità di test richiesti, possiamo migliorare gradualmente la nostra base di codice senza interrompere gli obiettivi aziendali o introdurre rischi aggiuntivi.

2. Pianificare storie tecniche in base alle priorità aziendali

Se un albero cadesse nella foresta ma nessuno lo sentisse, si sentiva un rumore? Se in un progetto è presente un codice errato, ma quel modulo non dovrà mai essere modificato, esiste un debito tecnico?


Credo che quando un programmatore trova sgradevole guardare qualche vecchio modulo, questo di per sé non è un grosso problema. Molto peggio è ciò che accade quando è necessario aggiungere nuove funzionalità a questo modulo o espandere quello vecchio. Rispetto ad apportare modifiche a un codice ben scritto, tali attività hanno maggiori probabilità (e maggiori probabilità di superare la stima originale) e contengono più bug. A volte molto di più. Per proteggerci da questo tipo di problemi, proviamo a pianificare i refactoring in modo che vengano eseguiti prima di scrivere nuove funzionalità nello stesso posto.


Se le modifiche alle funzionalità e i refactoring sembrano piccoli, possono essere eseguiti insieme. La dimensione dell'attività selezionata empiricamente per la quale questo approccio sarà ottimale è di 3 giorni di lavoro per uno sviluppatore o meno. Quando è chiaro che c'è più lavoro, lo si divide in refactoring mantenendo il comportamento attuale e implementando nuove funzionalità.


Pertanto, l'ordine di lavoro per eliminare il debito tecnico è determinato dall'ordine delle attività aziendali in arretrato.


Il principio delle “priorità aziendali” ha un’altra applicazione. Uno dei problemi più comuni di cui soffrono gli sviluppatori che si sforzano di scrivere bene è la difficoltà di dedicare tempo all'ottimizzazione delle prestazioni, al miglioramento della manutenibilità o ad altre cose che non sono direttamente incluse nel piano di lavoro. C'è quasi sempre la necessità aziendale di questi miglioramenti. Chi non desidera che il sistema funzioni più velocemente, sia più stabile e sia più economico da mantenere? Tutti questi benefici possono essere valutati e, sulla base di questa valutazione, le attività di miglioramento possono essere inserite nel backlog, insieme a qualsiasi altra.


Quindi, se desideri ottimizzare le prestazioni, ma invece devi correggere un altro noioso bug, forse semplicemente non sai come spiegare i vantaggi dell'ottimizzazione in un linguaggio comprensibile al proprietario del prodotto.

3. Lascia il codice più pulito di prima

Quasi tutti i codici, tranne quello scritto di recente, restano un po’ indietro rispetto all’attuale idea di bellezza nel campo dello stile e dell’architettura. Quando è necessario modificare il codice come parte di un'attività, è considerata buona pratica apportare tutti i miglioramenti sicuri possibili nell'area interessata. Cosa potrebbe essere?

  • Portare i moduli allo stile attuale.
  • Modifica dei nomi delle variabili interne in nomi più comprensibili.
  • Semplifica l'implementazione mantenendo il comportamento.
  • Refactoring locali che non introducono modifiche su larga scala ad altri moduli.

Si prevede che questi miglioramenti miglioreranno il codice, ma non aumenteranno in modo significativo il costo di sviluppo o test.


Grazie a questo principio, la qualità del codice aumenta gradualmente in background, anche laddove non erano previsti refactoring separati. Inoltre, più spesso lavoriamo su una determinata parte del sistema, migliore sarà il codice per quella parte. Un bel contrasto con i progetti in cui lo sviluppatore dedica la maggior parte del tempo alle parti con il codice peggiore.

4. Qualunque cosa accada, il sistema deve rimanere funzionante.

Uno dei principi di base di SCRUM afferma che alla fine di ogni sprint il sistema dovrebbe raggiungere uno stato stabile.


“Entro la fine dello sprint, l'incremento dovrebbe essere pronto, il che significa che soddisfa i criteri di preparazione dello Scrum Team ed è pronto per l'uso. Dovrebbe essere pronto per l’uso, indipendentemente dalla decisione del proprietario del prodotto di rilasciarlo o ritardarlo”.

Qualsiasi intervento volto all'eliminazione del debito tecnico viene svolto nel rispetto di questo principio.


Le grandi trasformazioni sono necessariamente scomposte in modo che ogni singola fase possa essere completata in un unico sprint. Ad esempio, abbiamo modificato il sistema di compilazione in due fasi (Angular 1.x: creeping webpack, lurking grunt)


Lavoriamo con VCS secondo principi vicini al classico gitflow. Lo sviluppo viene effettuato in rami di funzionalità, i test vengono eseguiti lì. Di norma, un tale ramo non dura più di uno sprint di due settimane. Un ramo che vive più a lungo comporta quasi sempre costi aggiuntivi.


La nostra esperienza conferma chiaramente questo schema. Ogni volta che non riuscivamo a completare un ampio refactoring in due settimane, era un dolore e una sofferenza. E più lungo era il compito e più a lungo viveva il ramo aperto, più lento era il lavoro e maggiori erano i problemi.


La necessità di essere sempre a pochi passi da un rilascio stabile crea uno dei problemi ingegneristici più difficili e interessanti: trovare la scomposizione ottimale dei piani strategici. I cambiamenti su larga scala possono essere suddivisi in fasi separate e indipendenti. Si consiglia di iniziare a ricevere i benefici il prima possibile. Quanto meglio viene eseguita questa suddivisione del lavoro, tanto maggiori sono le possibilità di portare a termine il lavoro.

Come si presenta il nostro processo

Una volta per ogni rilascio eseguiamo una revisione dettagliata del backlog tecnico:

  • Chiudiamo storie irrilevanti (pertinenza persa, realizzate come parte di qualcos'altro, duplicati).
  • Aggiorniamo la descrizione dove è cambiata la visione del problema.

Quando le storie aziendali appaiono all'orizzonte, viene effettuata un'analisi tecnica e tutte le storie tecniche che potrebbero aiutare nell'implementazione vengono associate alla storia aziendale.


In preparazione alla pianificazione dello sprint:

  • Controlliamo le connessioni tra storie tecniche e aziendali.
  • Colleghiamo tutti i bug correlati a storie tecniche che possono essere risolte a buon mercato nello stesso posto.

Come formare la parte tecnica del backlog

Quando ho assunto il ruolo di responsabile del team, ho chiesto a ciascuno sviluppatore e al QA quali miglioramenti al prodotto desideravano maggiormente apportare. La maggior parte delle richieste riguardavano miglioramenti tecnici alla piattaforma e refactoring. Come ha dimostrato l'esperienza successiva, tutti i principali problemi tecnici del prodotto sono stati inclusi in questa serie di desideri. Quindi puoi utilizzare questa pratica per creare rapidamente un arretrato tecnico da zero o avere un'idea generale dello stato del debito tecnico in un nuovo progetto.


L'attuale riempimento dell'arretrato con compiti tecnici avviene grazie alle pratiche sopra descritte e non richiede sforzi o analisi separati. Inoltre, al portafoglio ordini vengono aggiunte nuove idee per il miglioramento tecnico del prodotto. Questo viene fatto da qualsiasi membro del team che ha avuto un'idea del genere. La cosa principale in questa fase è non perdere l'idea. Il chiarimento e la determinazione delle priorità avvengono successivamente, durante la pianificazione del lavoro.

conclusioni

  • Il debito tecnico è inevitabile.
  • Per la maggior parte dei progetti, l’eliminazione del debito tecnico rappresenta un buon investimento di impegno.
  • Se il debito tecnico non viene affrontato, la velocità di sviluppo si avvicinerà gradualmente allo zero.
  • La tentazione di buttare via tutto e riscrivere può uccidere o paralizzare seriamente il tuo progetto.
  • I benefici derivanti dall’eliminazione del debito tecnico dovrebbero essere inquadrati in termini di vantaggi aziendali, altrimenti c’è il rischio che le attività volte a creare nuove funzionalità siano sempre considerate più importanti.
  • Vale la pena gestire i compiti per eliminare il debito tecnico. Tali attività non sono diverse dalle altre attività del progetto in termini di contabilità, pianificazione e definizione delle priorità.
  • Si verificano regolarmente situazioni in cui è possibile ridurre il debito tecnico e risolvere un problema aziendale allo stesso tempo in modo più economico rispetto a farlo separatamente. Queste opportunità devono essere sfruttate.
  • Convenzioni di stile di codice e processi di revisione attenti e aggiornati tempestivamente aiutano a rallentare l'emergere di nuovo debito tecnico.
  • Le iterazioni brevi sono utili tanto per i refactoring quanto per lo sviluppo di nuove funzionalità.
  • Il team di solito sa dove si trova il debito tecnico nel progetto e quanto è grave. Vale la pena utilizzare queste conoscenze per farsi un'idea del debito tecnico del progetto.

Nella mia risposta toccherò non solo le Grandi Case, ma anche alcune altre Case di cui ho potuto ottenere informazioni.

1.Chiave a stella - "L'inverno sta arrivando". Significa che la pace e la sicurezza sono temporanee e illusorie; bisogna sempre essere preparati ai disastri e alle guerre per affrontare il pericolo armati di tutto punto. A Westeros, l'inverno non è solo una stagione che dura per anni, ma anche un simbolo di prove difficili E in effetti questo motto non riguarda solo la Casa degli Stark, ma l'intero Paese.

2. Lannister- Sembra che Casa Lannister abbia due motti, uno dei quali conferma un formidabile stemma -" Ascolta il mio ruggito!", il secondo, equivalente a un modo di dire, ma che suona un ordine di grandezza più spesso del primo - " I Lannister pagano sempre i loro debiti". Il primo motto può essere attribuito direttamente allo stemma. Lo stemma dei Lannister raffigura leone rampante- "un leone ruggente", e il motto "Ascolta il mio ruggito" lo integra direttamente, è anche la prova che il leone è il re degli animali e che i Lannister occupano una posizione elevata nella società. Il detto "Un Lannister paga sempre i suoi debiti" è principalmente associato alla Banca di Ferro di Braavos "La Banca di Ferro riceverà sempre ciò che gli è dovuto". In secondo luogo, "Un Lannister paga sempre i propri debiti" significa che i Lannister non dimenticano mai coloro che li hanno aiutati e che i Lannister non perdonano mai i torti subiti.

3. Baratheon - "Siamo furiosi". originariamente apparteneva ai Durrandon di Storm's End. Orys Baratheon (il fratello illegittimo di Aegon I il Conquistatore), dopo aver ucciso Argilac l'Arrogante, l'ultimo Signore delle Terre della Tempesta, adottò il suo motto. Ma il motto fu tradotto troppo letteralmente. Dà una traduzione logica del motto" La rabbia è il nostro elemento", con la spiegazione del suo significato" La rabbia è il nostro elemento, il che significa: quando ci fai arrabbiare, getti il ​​pesce in mare, dove ci sentiamo benissimo.“Cioè, per i Baratheon, una violenta manifestazione di emozioni a scapito della fredda ragione non è un vizio.

4. Greyjoy - "Non seminiamo"I Greyjoy sono per lo più pirati. Il territorio delle loro terre si trova su nude rocce e sabbia. Il motto di questa casa è un messaggio diretto che i Greyjoy non lavorano la terra (che in realtà non esiste). Non seminano nulla e non crescono, derubano chi ha i raccolti e il bottino, poiché non hanno e non possono avere il proprio.

5. Targaryen - "Fuoco e sangue". Il motto Targaryen può essere interpretato in due modi. Il primo - Aegon il Conquistatore e le sue due sorelle, su tre draghi, soggiogarono Westeros, che si chiama "con lui e la spada". tramontosolitudine) - " I Targaryen sono dragonidi, hanno il sangue dell'antica Valyria e dei draghi, oltre a un bonus di immunità al fuoco e addomesticano i draghi. Quando i Targaryen dicono Fuoco e Sangue, lo ricordano a coloro che se ne sono improvvisamente dimenticati."

6. Arryns - "Alto come l'onore"Da un lato, la Casata di Arryn, seguendo l'esempio di Jon Arryn, si preoccupava di preservare l'onore. Jon non poteva essere intimidito o corrotto. E nelle terre di Westeros era impossibile trovare qualcuno che si preoccupasse più di preservare l'onore che di gli Arryn. Ma dopo la morte di Jon, probabilmente un'altra opzione è più applicabile: l'arroganza aristocratica, il disprezzo per quelli di status inferiore, dicono, "da dove vieni".

7. Tarly - "Primo in battaglia"La Casata di Tarly ha dato i natali a molti grandi guerrieri e generali eccezionali, come conferma questo motto.

8. Tully - "Famiglia, dovere, onore"La Casa Tully è leale soprattutto verso i suoi legami familiari. Il dovere e l'onore vengono dopo di loro, ma la famiglia viene prima di tutto. La Casa Tully ha sostenuto Rob Stark nella Guerra dei Cinque Re, per la quale ha pagato.

9. Martells - "Inflessibile, inflessibile, inflessibile". Un modello di orgoglio e inflessibilità. I ​​Martell sono l'unica casa che i Targaryen non hanno potuto prendere con la forza. E dal comportamento dei personaggi di questa casa è abbastanza ovvio che sono testardi e irremovibili. Non hanno bisogno del le leggi dei Signori, l'approvazione dei Re, sono da soli, ma mostrano chiaramente che non sono pronti a arrendersi.

10. Tyrell - "Crescendo diventiamo più forti". Il motto della casa Tyrell fu confermato dal loro esercito, il cui numero non poteva essere paragonato a nessun esercito di Westeros. I Tyrell avevano anche un "cuscino" sotto forma di ricchezza che avevano accumulato. Considerando che il cappotto Lo stemma di questa casa raffigura una rosa, con essa si può anche tracciare un parallelo Da un piccolo germoglio a un enorme cespuglio di rose. Così i membri della casa Tyrell, accumulando gradualmente forza, svilupparono e rafforzarono le loro posizioni. Tuttavia, come Olenna stessa detto, non sono affatto guerrieri.

11. Boltone -"Le nostre lame sono affilate". Questo motto serve piuttosto da monito ai nemici (e non solo) della famiglia Bolton. I rappresentanti di questa casa hanno una cupa reputazione; nei libri indossavano persino mantelli di pelle umana e con essa decoravano le mura dei loro castelli : "Un uomo nudo non ha segreti, ma un uomo scuoiato lo è ancora di più." "Le nostre lame sono affilate" - a quanto pare può anche significare lame per scuoiare la carne.

12. Mormont - "Qui siamo". Il motto, che, secondo Sunsetsolitude, è anche tradotto erroneamente in russo." Eccoci qui - può significare "Ecco le nostre terre", che a sua volta significa "Un'isola piccola ma orgogliosa che non disturba nessuno, ma può definirsi da sola. Ecco le nostre terre, ricordatelo quando verrai qui, noi sarà avvisato." Oppure può essere tradotto come "Su questo stiamo in piedi" - il che sarebbe un'indicazione diretta della forza della testardaggine dei Mormont"

13. Frey - "Stiamo fianco a fianco"I Frey apprezzavano i legami familiari e l'inviolabilità di questa parola, che è ciò che rifletteva questo motto. Da lì, Walder Frey nutrì un indicibile rancore nei confronti di Rob Stark, che non aveva mantenuto la sua promessa di sposare sua figlia, il che portò a tristi conseguenze.

"Un Lannister paga sempre i suoi debiti." © FFG ( Jason A. Engle)

"I Lannister pagano sempre i loro debiti"(Anche: "Un Lannister paga sempre i suoi debiti" ascolta)) è un detto popolare nei Sette Regni sulla Casa Lannister e un'espressione preferita di Tyrion Lannister. Non è meno famoso del motto “ufficiale” della casa, “Hear me roar!” Questa espressione ha un doppio significato. Da un lato, significa che i Lannister, in quanto casata più ricca dello stato, sono sempre pronti a pagare i conti e a ringraziare chi li ha aiutati, o a promettere ricompense in futuro: si può sempre contare sulla generosità e sull'impegno dei Lannister. “leoni”. Ma questo motto ha anche un secondo significato minaccioso: i Lannister non dimenticano gli insulti loro inflitti e si vendicheranno sicuramente dei delinquenti.

Nella bocca di Cersei Lannister, il detto risuonava in un discorso diretto contro lo stesso Tyrion: Cersei accusava suo fratello di intrighi contro di lei e Joffrey e cercava di ricattare Alaya catturata. Più tardi, trovandosi a capo dello stato, Cersei usò le stesse parole per giustificare la sua decisione di smettere di pagare i debiti pubblici alla Banca di Ferro di Braavos: i Lannister pagano sempre i loro debiti, e questo debito prima o poi verrà saldato. In seguito menzionò il detto in un dialogo con Balman Birch e Falisa Stokeworth, promettendo loro una ricompensa per il loro aiuto, e poi inviò il Tyroshi che aveva cercato di ingannarla dal boia con le parole "I Lannister pagano i loro debiti, e tu pagherai pure."

Tywin Lannister ha menzionato il detto in una conversazione con Tyrion, giustificando la necessità di dare Harrenhal a Petyr Baelish, poiché lui stesso lo desiderava. Lo stesso Tyrion ripeté immediatamente le parole sui debiti, chiedendo una ricompensa per se stesso per i suoi servizi come Primo Cavaliere. Shae ripeté il detto, ricordando a Tyrion la sua promessa di riportarla nella casa di città. Avendo saputo della defezione dei Westerling a favore di Robb Stark, Tyrion pensò tra sé che Tywin avrebbe sicuramente punito i traditori e ricordò il detto.

Jaime Lannister la ricordò a Urswick, cercando di sedurlo con la ricchezza, e in seguito, avendo perso la mano, ripeté a se stesso il detto, alimentando la sua sete di vendetta e voglia di vivere. Disse a Brienne di Tarth di averla salvata dallo stupro in segno di gratitudine per l'affondamento della galea di Robin Rieger all'inizio del loro viaggio, ricordando ancora una volta il detto. Successivamente ha ripetuto queste parole in una conversazione con Varys, spiegando così il suo desiderio di liberare Tyrion. Dopo aver rimosso Edmure Tully dal patibolo presso le mura di Delta delle Acque, Jaime pensò tra sé: "I Lannister stanno pagando i loro debiti e tu sei l'unica moneta che mi resta".

Lo stesso Edmure Tully ricordò il detto dopo aver appreso dell'omicidio di Willem Lannister e Theon Frey da parte di Rickard Karstark. Roose Bolton, parlando della sua intenzione di lasciare Harrenhal e affidarlo a Vargo Howth, ha detto: "I Lannister non sono gli unici a pagare i loro debiti". Jaime ripeté il detto quando salutò i Brave Boys lasciando il castello, suggerendo che si sarebbe vendicato di loro, e poi, tornando al castello per Brienne, rivolse le stesse parole a Vargo Haught, dicendo che avrebbe ricevuto un riscatto sia per Jaime che per Brienne

Pratiche tecnologiche di gestione del debito in un unico team


Circa un anno fa, il nostro team è passato da una fase di rapida crescita delle funzionalità a uno sviluppo più fluido con particolare attenzione al miglioramento della qualità. A questo punto, i nostri prodotti hanno accumulato una notevole quantità di soluzioni non ottimali, codice brutto e librerie obsolete. Bisognava fare qualcosa riguardo a tutto questo.


Ad oggi siamo riusciti a costruire un processo che rende la lotta al debito tecnico prevedibile, indolore e inevitabile.


Cosa abbiamo ottenuto come risultato:

  • La squadra è felice. La retrospettiva del rilascio include regolarmente punti positivi sul miglioramento della tecnologia e sulla riduzione del debito tecnico.
  • Per diversi rilasci trimestrali consecutivi, siamo stati in grado di aumentare la funzionalità senza aumentare il numero di righe di codice nel progetto. La rimozione del codice non necessario e la semplificazione di ciò che era necessario hanno ridotto le dimensioni della base di codice per le funzionalità esistenti. E questa riduzione ha più o meno coinciso in scala con il nuovo codice che implementa la nuova funzionalità.
  • Durante i refactoring e gli aggiornamenti, il prodotto è sempre funzionante. Ogni due settimane rilasciamo una versione provvisoria completamente funzionante.

Lasciate che vi spieghi come abbiamo raggiunto questo obiettivo.

Cos’è il debito tecnico

La mia definizione operativa di debito tecnico è la quantità di lavoro che deve essere svolta per far sì che un progetto soddisfi la visione di ciò che è eccezionale del team. Si noti che il debito tecnico può sorgere non solo a causa dell'uso liberale delle stampelle nello sviluppo, ma anche a causa del cambiamento delle idee sulla bellezza. Ad esempio, le pratiche comuni del settore sono cambiate. Oppure gli sviluppatori si sono innamorati dell'OOP e si sono innamorati della programmazione funzionale. Oppure il quadro un tempo di moda non è più una torta ed è diventato difficile trovare specialisti che vorrebbero scriverci sopra.


Tuttavia, la causa principale del debito tecnico è l’entropia in tutta la sua diversità. Unit test disabilitati, commenti obsoleti che hanno perso il contatto con il codice, decisioni architetturali infruttuose, implementazione di funzionalità che nessuno utilizza più, basi per un futuro che non è arrivato e molto, molto altro ancora.


Ne consegue che la comparsa del debito tecnico è inevitabile in qualsiasi progetto di lunga durata.

Quando il debito tecnico non è un problema

Perché il debito tecnico è negativo? Aumenta il costo dell’ulteriore sviluppo a causa di una serie di fattori:

  • La velocità di implementazione delle nuove funzionalità è ridotta.
  • Aumenta la probabilità di regressioni durante la correzione dei difetti.
  • Il processo di sviluppo diventa meno prevedibile e quindi meno gestibile.
  • Il processo di introduzione di un nuovo sviluppatore nel progetto si sta allungando.

Questa perdita è talvolta chiamata "interesse sul debito tecnico"


Ci sono situazioni in cui queste perdite sono più economiche che eliminare il debito tecnico:

  • La fine della vita del progetto è vicina. Tieni presente che questa non è la fine dell'aggiunta di funzionalità, ma il momento in cui puoi smettere di sprecare gli sforzi dei programmatori anche per il supporto. Questa categoria comprende anche prototipi unici, dimostrazioni uniche per mostre, ecc.
  • Il valore del tempo di sviluppo attuale è molto più elevato di quanto previsto in futuro. Correzioni urgenti a una scadenza fissa, startup che stanno finendo i soldi dal prossimo round di finanziamento, ecc. In questi casi, la riparazione del debito tecnico può essere ritardata fino a quando la foga del momento non si sarà calmata. Ci sono progetti che non escono dallo stato di emergenza, ma i consigli di questo articolo non li aiuteranno comunque.

Cosa fare con il debito tecnico? Approcci falliti

Approccio n.1. “Non abbiamo tempo, la liberatoria deve essere presentata ieri”

Il desiderio di rispettare la scadenza di domani ad ogni costo, a scapito della velocità di sviluppo di dopodomani.


A volte una struttura prefabbricata realizzata con le stampelle è una scelta oggettivamente corretta. Nella mia pratica, questo è stato espresso più chiaramente quando si realizzavano versioni demo per le mostre. La data dell’evento è fissata rigorosamente; se non sei arrivato in tempo per una mostra importante, il prossimo tentativo sarà tra un anno. In questo caso puoi mostrare il prodotto “fuori dalle tue mani”, evitando attentamente ogni bug. Come ingegnere, è spiacevole per me realizzare tali progetti, ma le stampelle in essi contenute sono giustificate.


Quando realizzi un prodotto che durerà a lungo, tutto è diverso. Rispettare la scadenza a causa di soluzioni tecniche dubbie è un piacere costoso. Il costo totale è:

  1. dalla realizzazione della stampella stessa,
  2. dalla sua successiva sostituzione con una soluzione a tutti gli effetti,
  3. dalla sofferenza di avere una stampella tra i punti precedenti.

Il secondo punto è molto facile da sottovalutare, e c’è il rischio di non pensare al terzo, quello più costoso in assoluto.


Quando incontri un responsabile tecnologico con gli occhi tremanti a una conferenza, potrebbe scoprire che è stato l'incubo di eseguire il debug infinito di un progetto fatto con le stampelle a portarlo in questo stato.


Approccio n. 2. “Sì, qui bisogna buttare tutto e riscriverlo”

Quanto peggiore è la situazione debitoria tecnica, tanto più forte è la tentazione di seppellire l'intero codice del progetto e riscrivere tutto da capo. Questo è uno dei classici errori che possono uccidere l’intero progetto.


L'argomento è così ben trattato nel famoso articolo di Joel Spolsky che non vedo il motivo di presentare le mie argomentazioni.

Approccio n. 3. "Effettueremo il refactoring di notte e nei fine settimana in modo che il manager non lo scopra."

Sostenere la necessità di eliminare il debito tecnico in termini di vantaggi aziendali non è sempre facile. Il team di sviluppo potrebbe essere tentato di aggirare gli spigoli e avviare un importante refactoring sul posto. Questo può essere fatto durante le ore non lavorative, nelle pause tra altre attività o “in coda” ad altre attività gonfiando le stime.


Cosa c'è di male? Oh, un sacco di cose:

  • La ridotta trasparenza mina la fiducia tra il management e il team. Spesso i tentativi successivi di correggere la situazione imponendo disciplina e stringendo le viti porteranno a un ulteriore deterioramento del lavoro di squadra.
  • Una situazione radicata in cui le priorità del team e del management sono in conflitto provoca demotivazione da entrambe le parti.
  • I frutti del refactoring vengono inclusi nel prodotto in modi imprevedibili e causano bug di regressione dove non sono previsti. Nei team consapevoli, ciò porta a un carico improvviso e non pianificato sul QA. Nell'inconscio entra in produzione e lì si rompe.

Dopo che il team ha utilizzato questa ricetta, gli occhi del management iniziano a tremare.

I nostri principi

1. Aggiungere compiti tecnici all'arretrato generale

Esistono numerosi modelli nella vita delle attività nei progetti:

  • Un compito che non è in arretrato ha meno possibilità di entrare nel lavoro.
  • Un compito senza una formulazione chiara ha meno possibilità di entrare nel lavoro.
  • Un compito che non può essere stimato con un alto grado di sicurezza ha meno possibilità di entrare nel lavoro.
  • Un'attività di grandi dimensioni attenderà più a lungo in coda rispetto a una piccola.

Maxim Dorofeev parla molto bene di queste cose nella sua “Tecnica della casella di posta vuota”


Per evitare l'accumulo del debito tecnico, i lavori per la sua eliminazione dovrebbero essere completati tenendo conto dei principi sopra elencati.


Tutte le attività, tranne quelle più piccole, sono elencate nel backlog. In questo modo hanno la possibilità di essere svolti non solo nel tempo libero, ma anche come parte del lavoro pianificato. Inoltre, tali compiti sono più difficili da perdere completamente di vista: il backlog viene esaminato più spesso e più da vicino rispetto alle TODO nel codice, pezzi di carta sul monitor, pagine wiki abbandonate, tovaglioli macchiati di tè con diagrammi e altro fonti di informazione.

  • Se nel codice è presente una TODO non banale, contiene un collegamento all'attività nel backlog. Verifichiamo il rispetto di questo principio in fase di revisione del codice e non accettiamo TODO complessi senza riferimenti.

    Potrebbe esserci un dramma dietro il commento.

    Una volta, accanto a un TODO del genere c'era scritto: “Stampella. Il Product Owner mi ha costretto a farlo. Toglietela il più presto possibile."

  • Quando uno sviluppatore si rende conto che qualche posto richiede il refactoring, crea un problema nel backlog.
  • Quando uno sviluppatore desidera migliorare la piattaforma, crea un'attività nel backlog.
  • I piani architettonici a lungo termine vengono inseriti nell'arretrato sotto forma di compiti separati non appena si ha sufficiente certezza almeno sui primi passi.

Finché tali modifiche rimangono poco costose in termini di costi di sviluppo e quantità di test richiesti, possiamo migliorare gradualmente la nostra base di codice senza interrompere gli obiettivi aziendali o introdurre rischi aggiuntivi.

2. Pianificare storie tecniche in base alle priorità aziendali

Se un albero cadesse nella foresta ma nessuno lo sentisse, si sentiva un rumore? Se in un progetto è presente un codice errato, ma quel modulo non dovrà mai essere modificato, esiste un debito tecnico?


Credo che quando un programmatore trova sgradevole guardare qualche vecchio modulo, questo di per sé non è un grosso problema. Molto peggio è ciò che accade quando è necessario aggiungere nuove funzionalità a questo modulo o espandere quello vecchio. Rispetto ad apportare modifiche a un codice ben scritto, tali attività hanno maggiori probabilità (e maggiori probabilità di superare la stima originale) e contengono più bug. A volte molto di più. Per proteggerci da questo tipo di problemi, proviamo a pianificare i refactoring in modo che vengano eseguiti prima di scrivere nuove funzionalità nello stesso posto.


Se le modifiche alle funzionalità e i refactoring sembrano piccoli, possono essere eseguiti insieme. La dimensione dell'attività selezionata empiricamente per la quale questo approccio sarà ottimale è di 3 giorni di lavoro per uno sviluppatore o meno. Quando è chiaro che c'è più lavoro, lo si divide in refactoring mantenendo il comportamento attuale e implementando nuove funzionalità.


Pertanto, l'ordine di lavoro per eliminare il debito tecnico è determinato dall'ordine delle attività aziendali in arretrato.


Il principio delle “priorità aziendali” ha un’altra applicazione. Uno dei problemi più comuni di cui soffrono gli sviluppatori che si sforzano di scrivere bene è la difficoltà di dedicare tempo all'ottimizzazione delle prestazioni, al miglioramento della manutenibilità o ad altre cose che non sono direttamente incluse nel piano di lavoro. C'è quasi sempre la necessità aziendale di questi miglioramenti. Chi non desidera che il sistema funzioni più velocemente, sia più stabile e sia più economico da mantenere? Tutti questi benefici possono essere valutati e, sulla base di questa valutazione, le attività di miglioramento possono essere inserite nel backlog, insieme a qualsiasi altra.


Quindi, se desideri ottimizzare le prestazioni, ma invece devi correggere un altro noioso bug, forse semplicemente non sai come spiegare i vantaggi dell'ottimizzazione in un linguaggio comprensibile al proprietario del prodotto.

3. Lascia il codice più pulito di prima

Quasi tutti i codici, tranne quello scritto di recente, restano un po’ indietro rispetto all’attuale idea di bellezza nel campo dello stile e dell’architettura. Quando è necessario modificare il codice come parte di un'attività, è considerata buona pratica apportare tutti i miglioramenti sicuri possibili nell'area interessata. Cosa potrebbe essere?

  • Portare i moduli allo stile attuale.
  • Modifica dei nomi delle variabili interne in nomi più comprensibili.
  • Semplifica l'implementazione mantenendo il comportamento.
  • Refactoring locali che non introducono modifiche su larga scala ad altri moduli.

Si prevede che questi miglioramenti miglioreranno il codice, ma non aumenteranno in modo significativo il costo di sviluppo o test.


Grazie a questo principio, la qualità del codice aumenta gradualmente in background, anche laddove non erano previsti refactoring separati. Inoltre, più spesso lavoriamo su una determinata parte del sistema, migliore sarà il codice per quella parte. Un bel contrasto con i progetti in cui lo sviluppatore dedica la maggior parte del tempo alle parti con il codice peggiore.

4. Qualunque cosa accada, il sistema deve rimanere funzionante.

Uno dei principi di base di SCRUM afferma che alla fine di ogni sprint il sistema dovrebbe raggiungere uno stato stabile.


“Entro la fine dello sprint, l'incremento dovrebbe essere pronto, il che significa che soddisfa i criteri di preparazione dello Scrum Team ed è pronto per l'uso. Dovrebbe essere pronto per l’uso, indipendentemente dalla decisione del proprietario del prodotto di rilasciarlo o ritardarlo”.

Qualsiasi intervento volto all'eliminazione del debito tecnico viene svolto nel rispetto di questo principio.


Le grandi trasformazioni sono necessariamente scomposte in modo che ogni singola fase possa essere completata in un unico sprint. Ad esempio, abbiamo modificato il sistema di assemblaggio in due fasi ()


Lavoriamo con VCS secondo principi vicini al classico gitflow. Lo sviluppo viene effettuato in rami di funzionalità, i test vengono eseguiti lì. Di norma, un tale ramo non dura più di uno sprint di due settimane. Un ramo che vive più a lungo comporta quasi sempre costi aggiuntivi.


La nostra esperienza conferma chiaramente questo schema. Ogni volta che non riuscivamo a completare un ampio refactoring in due settimane, era un dolore e una sofferenza. E più lungo era il compito e più a lungo viveva il ramo aperto, più lento era il lavoro e maggiori erano i problemi.


La necessità di essere sempre a pochi passi da un rilascio stabile crea uno dei problemi ingegneristici più difficili e interessanti: trovare la scomposizione ottimale dei piani strategici. I cambiamenti su larga scala possono essere suddivisi in fasi separate e indipendenti. Si consiglia di iniziare a ricevere i benefici il prima possibile. Quanto meglio viene eseguita questa suddivisione del lavoro, tanto maggiori sono le possibilità di portare a termine il lavoro.

Come si presenta il nostro processo

Una volta per ogni rilascio eseguiamo una revisione dettagliata del backlog tecnico:

  • Chiudiamo storie irrilevanti (pertinenza persa, realizzate come parte di qualcos'altro, duplicati).
  • Aggiorniamo la descrizione dove è cambiata la visione del problema.

Quando le storie aziendali appaiono all'orizzonte, viene effettuata un'analisi tecnica e tutte le storie tecniche che potrebbero aiutare nell'implementazione vengono associate alla storia aziendale.


In preparazione alla pianificazione dello sprint:

  • Controlliamo le connessioni tra storie tecniche e aziendali.
  • Colleghiamo tutti i bug correlati a storie tecniche che possono essere risolte a buon mercato nello stesso posto.

Come formare la parte tecnica del backlog

Quando ho assunto il ruolo di responsabile del team, ho chiesto a ciascuno sviluppatore e al QA quali miglioramenti al prodotto desideravano maggiormente apportare. La maggior parte delle richieste riguardavano miglioramenti tecnici alla piattaforma e refactoring. Come ha dimostrato l'esperienza successiva, tutti i principali problemi tecnici del prodotto sono stati inclusi in questa serie di desideri. Quindi puoi utilizzare questa pratica per creare rapidamente un arretrato tecnico da zero o avere un'idea generale dello stato del debito tecnico in un nuovo progetto.


L'attuale riempimento dell'arretrato con compiti tecnici avviene grazie alle pratiche sopra descritte e non richiede sforzi o analisi separati. Inoltre, al portafoglio ordini vengono aggiunte nuove idee per il miglioramento tecnico del prodotto. Questo viene fatto da qualsiasi membro del team che ha avuto un'idea del genere. La cosa principale in questa fase è non perdere l'idea. Il chiarimento e la determinazione delle priorità avvengono successivamente, durante la pianificazione del lavoro.

conclusioni

  • Il debito tecnico è inevitabile.
  • Per la maggior parte dei progetti, l’eliminazione del debito tecnico rappresenta un buon investimento di impegno.
  • Se il debito tecnico non viene affrontato, la velocità di sviluppo si avvicinerà gradualmente allo zero.
  • La tentazione di buttare via tutto e riscrivere può uccidere o paralizzare seriamente il tuo progetto.
  • I benefici derivanti dall’eliminazione del debito tecnico dovrebbero essere inquadrati in termini di vantaggi aziendali, altrimenti c’è il rischio che le attività volte a creare nuove funzionalità siano sempre considerate più importanti.
  • Vale la pena gestire i compiti per eliminare il debito tecnico. Tali attività non sono diverse dalle altre attività del progetto in termini di contabilità, pianificazione e definizione delle priorità.
  • Si verificano regolarmente situazioni in cui è possibile ridurre il debito tecnico e risolvere un problema aziendale allo stesso tempo in modo più economico rispetto a farlo separatamente. Queste opportunità devono essere sfruttate.
  • Convenzioni di stile di codice e processi di revisione attenti e aggiornati tempestivamente aiutano a rallentare l'emergere di nuovo debito tecnico.
  • Le iterazioni brevi sono utili tanto per i refactoring quanto per lo sviluppo di nuove funzionalità.
  • Il team di solito sa dove si trova il debito tecnico nel progetto e quanto è grave. Vale la pena utilizzare queste conoscenze per farsi un'idea del debito tecnico del progetto.

CATEGORIE

ARTICOLI POPOLARI

2024 “kingad.ru” - esame ecografico di organi umani