Lannisterowie zawsze spłacają swoje długi. Jakie jest motto Lannisterów? Jurij Boldyrew oczernia drobnego subkremlowskiego blogera Rogersa

Praktyki zarządzania długiem technologicznym w jednym zespole


Około rok temu nasz zespół przeszedł z fazy szybkiego rozwoju funkcji do bardziej płynnego rozwoju, skupiając się na poprawie jakości. W tym momencie w naszych produktach zgromadziła się zauważalna ilość nieoptymalnych rozwiązań, brzydkiego kodu i przestarzałych bibliotek. Coś trzeba było z tym wszystkim zrobić.


Do tej pory udało nam się zbudować proces, który sprawia, że ​​walka z długiem technicznym jest przewidywalna, bezbolesna i nieunikniona.


Co otrzymaliśmy w rezultacie:

  • Zespół jest szczęśliwy. Retrospektywa wydań regularnie zawiera pozytywne punkty dotyczące ulepszania technologii i zmniejszania długu technicznego.
  • Przez kilka kwartalnych wydań z rzędu udało nam się zwiększyć funkcjonalność bez zwiększania liczby linii kodu w projekcie. Usunięcie niepotrzebnego kodu i uproszczenie tego, co było potrzebne, zmniejszyło rozmiar bazy kodu dla istniejących funkcjonalności. Skala tej redukcji z grubsza pokrywała się z nowym kodem wdrażającym nową funkcjonalność.
  • Podczas refaktoryzacji i aktualizacji produkt jest zawsze sprawny. Co dwa tygodnie publikujemy w pełni działającą wersję tymczasową.

Pozwól, że opowiem Ci, jak to osiągnęliśmy.

Co to jest dług techniczny

Moja robocza definicja długu technicznego to ilość pracy, jaką należy wykonać, aby projekt spełnił wizję zespołu dotyczącą tego, co wspaniałe. Należy pamiętać, że dług techniczny może powstać nie tylko w wyniku liberalnego stosowania kul w rozwoju, ale także w wyniku zmieniających się wyobrażeń o pięknie. Zmieniły się na przykład powszechne praktyki branżowe. Albo programiści przestali kochać OOP i zakochali się w programowaniu funkcjonalnym. Albo modny niegdyś framework przestał być bułką z masłem i trudno znaleźć specjalistów, którzy chcieliby na nim pisać.


Jednak główną przyczyną długu technicznego jest entropia w całej jej różnorodności. Wyłączone testy jednostkowe, przestarzałe komentarze, które straciły kontakt z kodem, nieudane decyzje dotyczące architektury, implementacja funkcji, z których nikt już nie korzysta, fundament przyszłości, która nie nadeszła i wiele, wiele więcej.


Wynika z tego, że pojawienie się długu technicznego jest nieuniknione w każdym długotrwałym projekcie.

Kiedy dług techniczny nie stanowi problemu

Dlaczego dług techniczny jest zły? Zwiększa to koszty dalszego rozwoju ze względu na szereg czynników:

  • Zmniejsza się szybkość wdrażania nowej funkcjonalności.
  • Zwiększa się prawdopodobieństwo regresji podczas korygowania defektów.
  • Proces rozwoju staje się mniej przewidywalny, a przez to trudniejszy w zarządzaniu.
  • Wydłuża się proces wdrażania nowego dewelopera do projektu.

Strata ta jest czasami nazywana „odsetki od długu technicznego”


Są sytuacje, w których straty te są tańsze niż wyeliminowanie długu technicznego:

  • Koniec życia projektu jest bliski. Uwaga, to nie koniec dodawania funkcjonalności, ale moment, w którym możesz przestać marnować wysiłek programisty także na wsparcie. W tej kategorii znajdują się także jednorazowe prototypy, jednorazowe dema na wystawy itp.
  • Wartość czasu poświęconego na rozwój jest teraz znacznie wyższa, niż oczekiwano w przyszłości. Pilne poprawki w ustalonym terminie, startupom, którym kończą się pieniądze z kolejnej rundy dofinansowania itp. W takich przypadkach naprawę długu technicznego można odłożyć do czasu, aż ostygnie gorączka chwili. Są projekty, które nie wyjdą ze stanu nadzwyczajnego, ale rady z tego artykułu i tak im nie pomogą.

Co zrobić z długiem technicznym? Nieudane podejścia

Podejście nr 1. „Nie mamy czasu, komunikat trzeba złożyć wczoraj”

Chęć dotrzymania za wszelką cenę jutrzejszego terminu, kosztem szybkości rozwoju pojutrze.


Czasami konstrukcja prefabrykowana wykonana z kul jest obiektywnie właściwym wyborem. W mojej praktyce najdobitniej wyraziło się to przy tworzeniu wersji demonstracyjnych na wystawy. Termin wydarzenia jest ściśle ustalony, jeśli nie zdążyliście na ważną wystawę, następna próba będzie za rok. W takim przypadku możesz wyświetlić produkt „z ręki”, ostrożnie unikając wszelkich błędów. Jako inżynierowi nieprzyjemnie jest mi robić takie projekty, ale kule w nich są uzasadnione.


Kiedy tworzysz produkt, który będzie trwał długo, wszystko jest inne. Dotrzymanie terminu ze względu na wątpliwe rozwiązania techniczne to kosztowna przyjemność. Całkowity koszt to:

  1. od wykonania samej kuli,
  2. od jego późniejszej wymiany na pełnoprawne rozwiązanie,
  3. z cierpienia związanego z posiadaniem kuli pomiędzy poprzednimi punktami.

Punkt drugi bardzo łatwo przecenić i istnieje ryzyko, że o trzecim, najdroższym, w ogóle nie pomyślimy.


Kiedy na konferencji spotykasz lidera technologii z łzawiącym okiem, może się okazać, że to koszmar ciągłego debugowania projektu wykonanego o kulach doprowadził go do tego stanu.


Podejście nr 2. „Tak, tutaj musimy wszystko wyrzucić i napisać od nowa”

Im gorsza sytuacja zadłużenia technicznego, tym silniejsza pokusa zakopania całego kodu projektu i napisania wszystkiego od nowa. To jeden z klasycznych błędów, który może zrujnować cały projekt.


Temat jest tak dobrze omówiony w słynnym artykule Joela Spolsky'ego, że nie widzę sensu przedstawiania własnych argumentów.

Podejście nr 3. „Będziemy refaktoryzowali w nocy i w weekendy, żeby menadżer się nie dowiedział”.

Argumentowanie o konieczności wyeliminowania długu technologicznego w kontekście korzyści biznesowych nie zawsze jest łatwe. Zespół programistów może ulec pokusie, aby ominąć ostre krawędzie i rozpocząć od razu większą refaktoryzację. Można to zrobić w godzinach wolnych od pracy, w przerwach między innymi zadaniami lub „w ogonie” innych zadań, zawyżając szacunki.


Co w tym złego? Och, cała masa rzeczy:

  • Zmniejszona przejrzystość podważa zaufanie między kierownictwem a zespołem. Często kolejne próby naprawienia sytuacji poprzez narzucenie dyscypliny i dokręcenie śrubek będą prowadzić do dalszego pogorszenia pracy zespołowej.
  • Ugruntowana sytuacja, w której priorytety zespołu i kierownictwa są sprzeczne, powoduje demotywację po obu stronach.
  • Owoce refaktoryzacji są włączane do produktu w nieprzewidywalny sposób i powodują błędy regresyjne tam, gdzie się ich nie spodziewano. W świadomych zespołach prowadzi to do nagłego i nieplanowanego obciążenia QA. W nieświadomości wchodzi do produkcji i tam ulega rozkładowi.

Gdy zespół zastosuje ten przepis, oczy kierownictwu zaczynają się mrugać.

Nasze zasady

1. Dodaj zadania techniczne do ogólnego backlogu

W życiu zadań w projektach istnieje wiele wzorców:

  • Zadanie, którego nie ma w backlogu, ma mniejsze szanse na dostanie się do pracy.
  • Zadanie bez jasnego sformułowania ma mniejsze szanse na dostanie się do pracy.
  • Zadanie, którego nie można oszacować z dużą pewnością, ma mniejsze szanse na dostanie się do pracy.
  • Duże zadanie będzie czekać dłużej w kolejce niż małe.

Maxim Dorofeev bardzo dobrze mówi o tych rzeczach w swojej „Technice pustej skrzynki odbiorczej”


Aby zapobiec narastaniu długu technicznego, prace nad jego eliminacją należy prowadzić z uwzględnieniem powyższych zasad.


Wszystkie zadania, z wyjątkiem tych najmniejszych, są spisywane w backlogu. Dzięki temu mają szansę realizować się nie tylko w czasie wolnym, ale także w ramach zaplanowanej pracy. Poza tym takie zadania trudniej całkowicie stracić z oczu - zaległości są przeglądane częściej i dokładniej niż TODO w kodzie, kawałki papieru na monitorze, porzucone strony wiki, poplamione herbatą serwetki ze schematami i inne źródła informacji.

  • Jeśli w kodzie znajduje się nietrywialne TODO, zawiera ono link do zadania w backlogu. Zgodność z tą zasadą sprawdzamy podczas przeglądu kodu i nie przyjmujemy skomplikowanych TODO bez referencji.

    Za komentarzem może kryć się dramat.

    Kiedyś przy takim TODO było napisane: „Kula. Właściciel produktu zmusił mnie do tego. Usuń jak najszybciej.”

  • Kiedy programista zorientuje się, że jakieś miejsce wymaga refaktoryzacji, tworzy problem w backlogu.
  • Kiedy programista ma ochotę ulepszyć platformę, tworzy zadanie w backlogu.
  • Długoterminowe plany architektoniczne odkładane są na później w formie odrębnych zadań, gdy tylko będzie wystarczająca pewność co do choćby pierwszych kroków.

Dopóki takie zmiany pozostaną niedrogie pod względem kosztów rozwoju i ilości wymaganych testów, możemy stopniowo udoskonalać naszą bazę kodu, nie zakłócając celów biznesowych ani nie wprowadzając dodatkowego ryzyka.

2. Planuj historie techniczne w oparciu o priorytety biznesowe

Jeśli drzewo upadło w lesie, ale nikt tego nie słyszał, czy słychać było dźwięk? Jeśli w projekcie jest zły kod, ale moduł nigdy nie będzie musiał być zmieniany, czy istnieje dług techniczny?


Uważam, że gdy programiście nieprzyjemnie jest patrzeć na jakiś stary moduł, samo w sobie nie jest to bardzo dużym problemem. Znacznie gorzej jest, gdy trzeba dodać nową funkcjonalność do tego modułu lub rozbudować starą. W porównaniu do wprowadzania zmian w dobrze napisanym kodzie, takie zadania są bardziej prawdopodobne (i częściej przekraczają pierwotne szacunki) i zawierają więcej błędów. Czasem dużo więcej. Aby zabezpieczyć się przed tego typu problemami, staramy się planować refaktoryzacje tak, aby zostały wykonane przed napisaniem nowej funkcjonalności w tym samym miejscu.


Jeśli zmiany funkcjonalności i refaktoryzacje wydają się niewielkie, można je wykonać razem. Empirycznie wybrany rozmiar zadania, dla którego to podejście będzie optymalne, to 3 dni pracy na jednego programistę lub mniej. Kiedy już widać, że pracy jest więcej, dzieli się ją na refaktoryzację przy zachowaniu obecnego zachowania i wdrożenie nowej funkcjonalności.


Tym samym o kolejności prac mających na celu eliminację długu technicznego decyduje kolejność zadań biznesowych w backlogu.


Zasada „priorytetów biznesowych” ma jeszcze inne zastosowanie. Jednym z typowych problemów, na jakie cierpią programiści, którzy starają się dobrze pisać, jest trudność w poświęceniu czasu na optymalizację wydajności, poprawę łatwości konserwacji lub inne rzeczy, które nie są bezpośrednio uwzględnione w planie pracy. Prawie zawsze istnieje potrzeba biznesowa wprowadzenia tych ulepszeń. Kto nie chciałby, aby system działał szybciej, stabilniej i był tańszy w utrzymaniu? Wszystkie te korzyści można ocenić i na podstawie tej oceny można umieścić w backlogu zadania usprawnień wraz z innymi.


Jeśli więc chcesz zoptymalizować wydajność, ale zamiast tego musisz naprawić kolejny nudny błąd, być może po prostu nie wiesz, jak wyjaśnić korzyści płynące z optymalizacji w języku zrozumiałym dla właściciela produktu.

3. Pozostaw kod czystszy niż był przed tobą

Prawie każdy kod, z wyjątkiem tego, który powstał bardzo niedawno, pozostaje nieco w tyle za obecną koncepcją piękna w dziedzinie stylu i architektury. Kiedy w ramach zadania konieczna jest zmiana kodu, za dobrą praktykę uważa się wprowadzenie wszystkich możliwych ulepszeń w zakresie bezpieczeństwa w danym obszarze. Co to mogło być?

  • Doprowadzenie modułów do obecnego stylu.
  • Zmiana nazw zmiennych wewnętrznych na bardziej zrozumiałe.
  • Uprość wdrożenie, zachowując zachowanie.
  • Lokalne refaktoryzacje, które nie wprowadzają zmian na dużą skalę w innych modułach.

Oczekuje się, że te ulepszenia sprawią, że kod będzie lepszy, ale nie zwiększą znacząco kosztów programowania lub testowania.


Dzięki tej zasadzie jakość kodu stopniowo wzrasta w tle, nawet w tych miejscach, gdzie nie planowano osobnych refaktoryzacji. Co więcej, im częściej pracujemy nad daną częścią systemu, tym lepszy jest kod dla tej części. Miły kontrast w stosunku do projektów, w których programista spędza najwięcej czasu na częściach z najgorszym kodem.

4. Bez względu na to, co się stanie, system musi pozostać sprawny.

Jedna z podstawowych zasad SCRUM mówi, że na koniec każdego sprintu system powinien osiągnąć stan stabilny.


„Na koniec sprintu przyrost powinien być gotowy, czyli spełnia kryteria gotowości Zespołu Scrumowego i jest gotowy do użycia. Powinien być gotowy do użycia, niezależnie od decyzji właściciela produktu o jego udostępnieniu lub opóźnieniu.”

Wszelkie prace mające na celu eliminację długu technicznego prowadzone są zgodnie z tą zasadą.


Duże transformacje są koniecznie rozkładane, aby każdy pojedynczy etap można było ukończyć w jednym sprincie. Na przykład zmieniliśmy system kompilacji w dwóch etapach (Angular 1.x: pełzający pakiet internetowy, czyhający chrząknięcie)


Współpracujemy z VCS według zasad bliskich klasycznemu gitflow. Rozwój odbywa się w gałęziach fabularnych, tam przeprowadzane są testy. Z reguły taka gałąź nie trwa dłużej niż jeden dwutygodniowy sprint. Oddział, który żyje dłużej, prawie zawsze wiąże się z dodatkowymi kosztami.


Nasze doświadczenie wyraźnie potwierdza tę prawidłowość. Za każdym razem, gdy nie udało nam się ukończyć dużej refaktoryzacji w ciągu dwóch tygodni, był to ból i cierpienie. Im dłuższe było zadanie i im dłużej żyła otwarta gałąź, tym wolniej szła praca i tym więcej było problemów.


Konieczność bycia zawsze kilka kroków od wydania stabilnego stwarza jeden z najtrudniejszych i najciekawszych problemów inżynierskich – znalezienie optymalnej dekompozycji planów strategicznych. Zmiany na dużą skalę można podzielić na osobne, niezależne etapy. Wskazane jest, aby rozpocząć pobieranie świadczeń jak najwcześniej. Im lepiej zostanie przeprowadzony ten podział pracy, tym większe są szanse na doprowadzenie zadania do końca.

Jak wygląda nasz proces

Raz na wydanie przeprowadzamy szczegółowy przegląd zaległości technicznych:

  • Zamykamy nieistotne historie (utracone znaczenie, utworzone jako część czegoś innego, duplikaty).
  • Aktualizujemy opis tam, gdzie zmieniła się wizja problemu.

Kiedy na horyzoncie pojawiają się historie biznesowe, przeprowadzana jest analiza techniczna i wszystkie historie techniczne, które pomogłyby we wdrożeniu, są kojarzone z historią biznesową.


W ramach przygotowań do planowania sprintu:

  • Sprawdzamy powiązania historii technicznej z biznesową.
  • Łączymy wszystkie powiązane błędy z historiami technicznymi, które można tanio naprawić w tym samym miejscu.

Jak utworzyć część techniczną backlogu

Kiedy objąłem rolę lidera zespołu, zapytałem każdego programistę i kontrolę jakości, jakie ulepszenia produktu najbardziej chcą wprowadzić. Większość zgłoszeń dotyczyła udoskonaleń technicznych platformy i refaktoryzacji. Jak pokazało dalsze doświadczenie, w tym zestawie życzeń uwzględniono wszystkie kluczowe problemy techniczne produktu. Można więc skorzystać z tej praktyki, aby szybko zbudować backlog techniczny od podstaw lub uzyskać ogólny pogląd na stan długu technicznego w nowym projekcie.


Bieżące zapełnianie backlogu zadaniami technicznymi następuje dzięki opisanym powyżej praktykom i nie wymaga odrębnych wysiłków ani analiz. Dodatkowo do backlogu dopisywane są nowe pomysły na techniczne udoskonalenie produktu. Robi to dowolny członek zespołu, który wpadł na taki pomysł. Najważniejsze na tym etapie to nie stracić pomysłu. Wyjaśnienie i określenie priorytetów następuje później, podczas planowania pracy.

wnioski

  • Dług technologiczny jest nieunikniony.
  • W przypadku większości projektów wyeliminowanie długu technicznego jest dobrą inwestycją wysiłku.
  • Jeżeli dług techniczny nie zostanie rozwiązany, tempo rozwoju będzie stopniowo zbliżać się do zera.
  • Pokusa wyrzucenia wszystkiego i napisania od nowa może zabić lub poważnie okaleczyć Twój projekt.
  • Korzyści z wyeliminowania długu technicznego należy ująć w kategoriach korzyści biznesowych, w przeciwnym razie istnieje ryzyko, że zadania tworzenia nowej funkcjonalności będą zawsze uważane za ważniejsze.
  • Zadaniami mającymi na celu eliminację długu technicznego warto się zająć. Zadania takie nie różnią się od innych zadań projektowych pod względem rachunkowości, planowania i ustalania priorytetów.
  • Regularnie pojawiają się sytuacje, w których można zmniejszyć dług techniczny i rozwiązać problem biznesowy jednocześnie taniej, niż robiąc to osobno. Należy wykorzystać te możliwości.
  • Przemyślane i terminowo aktualizowane konwencje dotyczące stylu kodu oraz procesy przeglądu pomagają spowolnić pojawianie się nowego długu technicznego.
  • Krótkie iteracje są równie przydatne przy refaktoryzacji, jak i przy opracowywaniu nowych funkcjonalności.
  • Zespół zazwyczaj wie, gdzie w projekcie znajduje się dług techniczny i jak bardzo jest on poważny. Tę wiedzę warto wykorzystać przy formułowaniu wyobrażenia o długu technicznym projektu.

W mojej odpowiedzi poruszę nie tylko Wielkie Domy, ale także kilka innych domów, o których udało mi się uzyskać informacje.

1.Klawisz gwiazdki - "Nadchodzi zima". Oznacza, że ​​pokój i bezpieczeństwo są tymczasowe i iluzoryczne; zawsze należy być przygotowanym na katastrofy i wojny, aby w pełni uzbrojony stawić czoła niebezpieczeństwu. W Westeros zima to nie tylko pora roku trwająca latami, ale także symbol trudnych prób I tak naprawdę to motto dotyczy nie tylko Domu Starków, ale całego kraju.

2. Lannisterowie- Wydaje się, że ród Lannisterów ma dwa motta, jedno potwierdzające potężny herb... Słuchajcie mego ryku!", drugie, równoważne powiedzeniu, ale brzmiące o rząd wielkości częściej niż pierwsze - " Lannisterowie zawsze spłacają swoje długi„. Pierwsze motto można przypisać bezpośrednio herbowi. Herb Lannisterów przedstawia szalejący lew- „ryczący lew”, a motto „Usłysz mój ryk” bezpośrednio go uzupełnia, jest to także dowód na to, że lew jest królem zwierząt, a Lannisterowie zajmują wysoką pozycję w społeczeństwie. Powiedzenie „Lannister zawsze spłaca swoje długi” kojarzy się przede wszystkim z Żelaznym Bankiem z Braavos. „Żelazny Bank zawsze dostanie to, co się należy”. Po drugie, „Lannisterowie zawsze spłacają swoje długi” oznacza, że ​​Lannisterowie nigdy nie zapominają o tych, którzy im pomogli i że Lannisterowie nigdy nie wybaczają wyrządzonych im krzywd.

3. Baratheon - "Jesteśmy wściekli„. pierwotnie należał do Durrandonów z Końca Burzy. Orys Baratheon (nieślubny brat Aegona I Zdobywcy), po zabiciu Argilaca Aroganckiego, ostatniego Władcy Krain Burzy, przyjął jego motto. Jednak motto zostało przetłumaczone zbyt dosłownie. Daje logiczne tłumaczenie motta” Gniew jest naszym żywiołem„, z wyjaśnieniem jego znaczenia” Złość jest naszym żywiołem, co oznacza, że ​​gdy nas rozzłościsz, wrzucasz rybę do morza, gdzie czuje się świetnie.„Oznacza to, że dla Baratheonów gwałtowne okazywanie emocji kosztem zimnego rozsądku nie jest wadą.

4. Greyjoy'a - "Nie siejemy„Greyjoyowie to w większości piraci. Terytorium ich ziem położone jest na gołych skałach i piasku. Motto tego domu to bezpośredni przekaz, że Greyjoyowie nie pracują na ziemi (która tak naprawdę nie istnieje). Nie sieją. czegokolwiek, a nie rosną, rabują tych, którzy mają plony i łupy, bo nie mają i nie mogą mieć własnego.

5. Targaryena - "Ogień i krew Motto Targaryenów można interpretować dwojako. Pierwszy – Aegon Zdobywca i jego dwie siostry na trzech smokach podbili Westeros, co nazywa się „nim i mieczem”. Opcja druga – (wspomniana wyżej samotność zachodu słońca) - " Targaryenowie są smoczymi dziećmi, mają krew Starożytnej Valyrii i smoki, a także premię do odporności na ogień i oswajanie smoków. Kiedy Targaryenowie mówią Ogień i Krew, przypominają tym, którzy nagle o tym zapomnieli."

6. Arrynsa - "Wysoki jak honor„Z jednej strony ród Arrynów, wzorując się na Jonie Arrynie, dbał o zachowanie honoru. Jona nie można było zastraszyć ani przekupić. A na ziemiach Westeros nie można było znaleźć nikogo, komu bardziej zależało na zachowaniu honoru niż na Arrynowie. Ale po śmierci Jona prawdopodobnie bardziej odpowiednia będzie inna opcja - arystokratyczna arogancja, pogarda dla osób o niższym statusie, mówią: „gdzie jesteś od nas”.

7. Tarly - "Pierwszy w bitwie„Ród Tarlych wydał na świat wielu wielkich wojowników i wybitnych generałów, co potwierdza to motto.

8. Tully - "Rodzina obowiązek honor„Ród Tully jest lojalny przede wszystkim wobec swoich więzi rodzinnych. Obowiązki i honor przychodzą po nich, ale rodzina jest na pierwszym miejscu. Ród Tully wspierał Roba Starka w Wojnie Pięciu Królów, za co zapłacił.

9. Martells - "Nieugięty, nieugięty, nieugięty". Wzór dumy i nieugiętości. Martellowie to jedyny ród, którego Targaryenowie nie byli w stanie zdobyć siłą. A z zachowania bohaterów tego rodu jasno wynika, że ​​są oni uparci i niewzruszeni. Nie potrzebują prawa Panów, akceptacja Królów, są zdani na siebie, ale wyraźnie pokazują, że nie są gotowi się poddać.

10. Tyrell - "Dorastając, stajemy się silniejsi Motto rodu Tyrellów potwierdziła ich armia, której liczebności nie można było porównać z żadną armią w Westeros. Tyrellowie mieli także „poduszkę” w postaci zgromadzonego przez siebie bogactwa. Biorąc pod uwagę, że płaszcz herbu tego domu przedstawia różę, można z nią także poprowadzić paralelę. Od małego pędu do ogromnego krzewu róży. Tak więc członkowie rodu Tyrellów, stopniowo gromadząc siły, rozwijali się i umacniali swoje pozycje. Jednak jak sama Olenna powiedział, że wcale nie są wojownikami.

11. Boltona -"Nasze ostrza są ostre To motto służy raczej jako przestroga dla wrogów (i nie tylko) rodu Boltonów. Przedstawiciele tego rodu mają ponurą reputację, w książkach nosili nawet płaszcze z ludzkiej skóry i ozdabiali nimi ściany swoich zamków : „Nagi mężczyzna nie ma tajemnic, ale człowiek obdarty ze skóry, a nawet więcej.” „Nasze ostrza są ostre” - najwyraźniej może również oznaczać ostrza do odzierania mięsa.

12. Mormonta - "Stoimy tutaj„. Motto, które według Sunsetsolitude jest również błędnie przetłumaczone na język rosyjski”. Tutaj stoimy - może oznaczać „Oto nasze ziemie”, co z kolei oznacza „Mała, ale dumna wyspa, która nikomu nie przeszkadza, ale może się sama określić. Oto nasze ziemie, pamiętajcie o tym, kiedy tu przyjedziecie, my ostrzegł.” Można to też przetłumaczyć jako „Na tym stoimy” – co byłoby bezpośrednim wskazaniem siły uporu Mormonta"

13. Frey - "Stoimy ramię w ramię„Freyowie cenili więzi rodzinne i nienaruszalność tego słowa, co odzwierciedlało to motto. Od tego momentu Walder Frey żywił niewypowiedzianą urazę do Roba Starka, który złamał obietnicę poślubienia jego córki, co miało smutne konsekwencje.

„Lannister zawsze spłaca swoje długi”. © FFG ( Jasona A. Engle’a)

„Lannisterowie zawsze spłacają swoje długi”(Również: „Lannister zawsze spłaca swoje długi” posłuchaj)) to popularne powiedzenie w Siedmiu Królestwach na temat rodu Lannisterów i ulubione wyrażenie Tyriona Lannistera. Jest nie mniej znane niż „oficjalne” motto domu: „Usłyszcie mój ryk!” Wyrażenie to ma podwójne znaczenie. Z jednej strony oznacza to, że Lannisterowie, jako najbogatszy ród w stanie, zawsze są gotowi zapłacić rachunki i podziękować tym, którzy im pomogli, lub obiecywać nagrody w przyszłości – zawsze można liczyć na hojność i zaangażowanie ze strony "krzyże". Ale to motto ma także drugie, groźne znaczenie: Lannisterowie nie zapominają o wyrządzonych im zniewagach i na pewno zemszczą się na sprawcach.

W ustach Cersei Lannister to powiedzenie zabrzmiało w przemówieniu skierowanym przeciwko samemu Tyrionowi – Cersei oskarżyła brata o intrygi przeciwko niej i Joffreyowi oraz próbowała szantażować schwytaną Alaya. Później, gdy znalazła się na czele państwa, Cersei tymi samymi słowami uzasadniała swoją decyzję o zaprzestaniu spłacania długów publicznych wobec Żelaznego Banku Braavos – Lannisterowie zawsze spłacają swoje długi, a dług ten prędzej czy później zostanie spłacony. Wspomniała później o tym powiedzeniu w rozmowie z Balmanem Birchem i Falisą Stokeworth, obiecując im nagrodę za pomoc, po czym wysłała Tyroshi, który próbował ją oszukać, do kata ze słowami: „Lannisterowie spłacają swoje długi, a ty zapłacisz zbyt."

Tywin Lannister wspomniał o tym powiedzeniu w rozmowie z Tyrionem, uzasadniając potrzebę oddania Harrenhal Petyrowi Baelishowi, gdyż sam tego chciał. Sam Tyrion natychmiast powtórzył słowa o długach, żądając dla siebie nagrody za swoje usługi jako namiestnika. Shae powtórzyła to powiedzenie, przypominając Tyrionowi o jego obietnicy umieszczenia jej z powrotem w kamienicy. Dowiedziawszy się o ucieczce Westerlingów na rzecz Robba Starka, Tyrion pomyślał, że Tywin z pewnością ukarze zdrajców i przypomniał sobie to powiedzenie.

Jaime Lannister przypominał o niej Urswickowi, próbując uwieść go bogactwem, a później, straciwszy rękę, powtarzał sobie to powiedzenie, podsycając swoje pragnienie zemsty i chęć życia. Powiedział Brienne z Tarth, że uratował ją przed gwałtem w podzięce za zatopienie galery Robina Riegera na początku ich podróży, ponownie przypominając sobie to powiedzenie. Później powtórzył te słowa w rozmowie z Varysem, tłumacząc w ten sposób swoją chęć uwolnienia Tyriona. Po zdjęciu Edmure'a Tully'ego z szafotu pod murami Riverrun, Jaime pomyślał: „Lannisterowie spłacają swoje długi, a ty jesteś jedyną monetą, jaka mi została”.

Sam Edmure Tully przypomniał sobie to powiedzenie, gdy dowiedział się o morderstwie Willema Lannistera i Theona Freya przez Rickarda Karstarka. Roose Bolton, mówiąc o swoim zamiarze opuszczenia Harrenhal i pozostawienia go Vargo Howthowi, powiedział: „Nie tylko Lannisterowie spłacają swoje długi”. Jaime powtórzył to powiedzenie, żegnając się z Dzielnymi Chłopcami opuszczając zamek, dając do zrozumienia, że ​​zemści się na nich, a następnie wracając do zamku po Brienne, tymi samymi słowami zwrócił się do Vargo Haughta, mówiąc, że otrzyma okup za Jaime'a i Brienne

Praktyki zarządzania długiem technologicznym w jednym zespole


Około rok temu nasz zespół przeszedł z fazy szybkiego rozwoju funkcji do bardziej płynnego rozwoju, skupiając się na poprawie jakości. W tym momencie w naszych produktach zgromadziła się zauważalna ilość nieoptymalnych rozwiązań, brzydkiego kodu i przestarzałych bibliotek. Coś trzeba było z tym wszystkim zrobić.


Do tej pory udało nam się zbudować proces, który sprawia, że ​​walka z długiem technicznym jest przewidywalna, bezbolesna i nieunikniona.


Co otrzymaliśmy w rezultacie:

  • Zespół jest szczęśliwy. Retrospektywa wydań regularnie zawiera pozytywne punkty dotyczące ulepszania technologii i zmniejszania długu technicznego.
  • Przez kilka kwartalnych wydań z rzędu udało nam się zwiększyć funkcjonalność bez zwiększania liczby linii kodu w projekcie. Usunięcie niepotrzebnego kodu i uproszczenie tego, co było potrzebne, zmniejszyło rozmiar bazy kodu dla istniejących funkcjonalności. Skala tej redukcji z grubsza pokrywała się z nowym kodem wdrażającym nową funkcjonalność.
  • Podczas refaktoryzacji i aktualizacji produkt jest zawsze sprawny. Co dwa tygodnie publikujemy w pełni działającą wersję tymczasową.

Pozwól, że opowiem Ci, jak to osiągnęliśmy.

Co to jest dług techniczny

Moja robocza definicja długu technicznego to ilość pracy, jaką należy wykonać, aby projekt spełnił wizję zespołu dotyczącą tego, co wspaniałe. Należy pamiętać, że dług techniczny może powstać nie tylko w wyniku liberalnego stosowania kul w rozwoju, ale także w wyniku zmieniających się wyobrażeń o pięknie. Zmieniły się na przykład powszechne praktyki branżowe. Albo programiści przestali kochać OOP i zakochali się w programowaniu funkcjonalnym. Albo modny niegdyś framework przestał być bułką z masłem i trudno znaleźć specjalistów, którzy chcieliby na nim pisać.


Jednak główną przyczyną długu technicznego jest entropia w całej jej różnorodności. Wyłączone testy jednostkowe, przestarzałe komentarze, które straciły kontakt z kodem, nieudane decyzje dotyczące architektury, implementacja funkcji, z których nikt już nie korzysta, fundament przyszłości, która nie nadeszła i wiele, wiele więcej.


Wynika z tego, że pojawienie się długu technicznego jest nieuniknione w każdym długotrwałym projekcie.

Kiedy dług techniczny nie stanowi problemu

Dlaczego dług techniczny jest zły? Zwiększa to koszty dalszego rozwoju ze względu na szereg czynników:

  • Zmniejsza się szybkość wdrażania nowej funkcjonalności.
  • Zwiększa się prawdopodobieństwo regresji podczas korygowania defektów.
  • Proces rozwoju staje się mniej przewidywalny, a przez to trudniejszy w zarządzaniu.
  • Wydłuża się proces wdrażania nowego dewelopera do projektu.

Strata ta jest czasami nazywana „odsetki od długu technicznego”


Są sytuacje, w których straty te są tańsze niż wyeliminowanie długu technicznego:

  • Koniec życia projektu jest bliski. Uwaga, to nie koniec dodawania funkcjonalności, ale moment, w którym możesz przestać marnować wysiłek programisty także na wsparcie. W tej kategorii znajdują się także jednorazowe prototypy, jednorazowe dema na wystawy itp.
  • Wartość czasu poświęconego na rozwój jest teraz znacznie wyższa, niż oczekiwano w przyszłości. Pilne poprawki w ustalonym terminie, startupom, którym kończą się pieniądze z kolejnej rundy dofinansowania itp. W takich przypadkach naprawę długu technicznego można odłożyć do czasu, aż ostygnie gorączka chwili. Są projekty, które nie wyjdą ze stanu nadzwyczajnego, ale rady z tego artykułu i tak im nie pomogą.

Co zrobić z długiem technicznym? Nieudane podejścia

Podejście nr 1. „Nie mamy czasu, komunikat trzeba złożyć wczoraj”

Chęć dotrzymania za wszelką cenę jutrzejszego terminu, kosztem szybkości rozwoju pojutrze.


Czasami konstrukcja prefabrykowana wykonana z kul jest obiektywnie właściwym wyborem. W mojej praktyce najdobitniej wyraziło się to przy tworzeniu wersji demonstracyjnych na wystawy. Termin wydarzenia jest ściśle ustalony, jeśli nie zdążyliście na ważną wystawę, następna próba będzie za rok. W takim przypadku możesz wyświetlić produkt „z ręki”, ostrożnie unikając wszelkich błędów. Jako inżynierowi nieprzyjemnie jest mi robić takie projekty, ale kule w nich są uzasadnione.


Kiedy tworzysz produkt, który będzie trwał długo, wszystko jest inne. Dotrzymanie terminu ze względu na wątpliwe rozwiązania techniczne to kosztowna przyjemność. Całkowity koszt to:

  1. od wykonania samej kuli,
  2. od jego późniejszej wymiany na pełnoprawne rozwiązanie,
  3. z cierpienia związanego z posiadaniem kuli pomiędzy poprzednimi punktami.

Punkt drugi bardzo łatwo przecenić i istnieje ryzyko, że o trzecim, najdroższym, w ogóle nie pomyślimy.


Kiedy na konferencji spotykasz lidera technologii z łzawiącym okiem, może się okazać, że to koszmar ciągłego debugowania projektu wykonanego o kulach doprowadził go do tego stanu.


Podejście nr 2. „Tak, tutaj musimy wszystko wyrzucić i napisać od nowa”

Im gorsza sytuacja zadłużenia technicznego, tym silniejsza pokusa zakopania całego kodu projektu i napisania wszystkiego od nowa. To jeden z klasycznych błędów, który może zrujnować cały projekt.


Temat jest tak dobrze omówiony w słynnym artykule Joela Spolsky'ego, że nie widzę sensu przedstawiania własnych argumentów.

Podejście nr 3. „Będziemy refaktoryzowali w nocy i w weekendy, żeby menadżer się nie dowiedział”.

Argumentowanie o konieczności wyeliminowania długu technologicznego w kontekście korzyści biznesowych nie zawsze jest łatwe. Zespół programistów może ulec pokusie, aby ominąć ostre krawędzie i rozpocząć od razu większą refaktoryzację. Można to zrobić w godzinach wolnych od pracy, w przerwach między innymi zadaniami lub „w ogonie” innych zadań, zawyżając szacunki.


Co w tym złego? Och, cała masa rzeczy:

  • Zmniejszona przejrzystość podważa zaufanie między kierownictwem a zespołem. Często kolejne próby naprawienia sytuacji poprzez narzucenie dyscypliny i dokręcenie śrubek będą prowadzić do dalszego pogorszenia pracy zespołowej.
  • Ugruntowana sytuacja, w której priorytety zespołu i kierownictwa są sprzeczne, powoduje demotywację po obu stronach.
  • Owoce refaktoryzacji są włączane do produktu w nieprzewidywalny sposób i powodują błędy regresyjne tam, gdzie się ich nie spodziewano. W świadomych zespołach prowadzi to do nagłego i nieplanowanego obciążenia QA. W nieświadomości wchodzi do produkcji i tam ulega rozkładowi.

Gdy zespół zastosuje ten przepis, oczy kierownictwu zaczynają się mrugać.

Nasze zasady

1. Dodaj zadania techniczne do ogólnego backlogu

W życiu zadań w projektach istnieje wiele wzorców:

  • Zadanie, którego nie ma w backlogu, ma mniejsze szanse na dostanie się do pracy.
  • Zadanie bez jasnego sformułowania ma mniejsze szanse na dostanie się do pracy.
  • Zadanie, którego nie można oszacować z dużą pewnością, ma mniejsze szanse na dostanie się do pracy.
  • Duże zadanie będzie czekać dłużej w kolejce niż małe.

Maxim Dorofeev bardzo dobrze mówi o tych rzeczach w swojej „Technice pustej skrzynki odbiorczej”


Aby zapobiec narastaniu długu technicznego, prace nad jego eliminacją należy prowadzić z uwzględnieniem powyższych zasad.


Wszystkie zadania, z wyjątkiem tych najmniejszych, są spisywane w backlogu. Dzięki temu mają szansę realizować się nie tylko w czasie wolnym, ale także w ramach zaplanowanej pracy. Poza tym takie zadania trudniej całkowicie stracić z oczu - zaległości są przeglądane częściej i dokładniej niż TODO w kodzie, kawałki papieru na monitorze, porzucone strony wiki, poplamione herbatą serwetki ze schematami i inne źródła informacji.

  • Jeśli w kodzie znajduje się nietrywialne TODO, zawiera ono link do zadania w backlogu. Zgodność z tą zasadą sprawdzamy podczas przeglądu kodu i nie przyjmujemy skomplikowanych TODO bez referencji.

    Za komentarzem może kryć się dramat.

    Kiedyś przy takim TODO było napisane: „Kula. Właściciel produktu zmusił mnie do tego. Usuń jak najszybciej.”

  • Kiedy programista zorientuje się, że jakieś miejsce wymaga refaktoryzacji, tworzy problem w backlogu.
  • Kiedy programista ma ochotę ulepszyć platformę, tworzy zadanie w backlogu.
  • Długoterminowe plany architektoniczne odkładane są na później w formie odrębnych zadań, gdy tylko będzie wystarczająca pewność co do choćby pierwszych kroków.

Dopóki takie zmiany pozostaną niedrogie pod względem kosztów rozwoju i ilości wymaganych testów, możemy stopniowo udoskonalać naszą bazę kodu, nie zakłócając celów biznesowych ani nie wprowadzając dodatkowego ryzyka.

2. Planuj historie techniczne w oparciu o priorytety biznesowe

Jeśli drzewo upadło w lesie, ale nikt tego nie słyszał, czy słychać było dźwięk? Jeśli w projekcie jest zły kod, ale moduł nigdy nie będzie musiał być zmieniany, czy istnieje dług techniczny?


Uważam, że gdy programiście nieprzyjemnie jest patrzeć na jakiś stary moduł, samo w sobie nie jest to bardzo dużym problemem. Znacznie gorzej jest, gdy trzeba dodać nową funkcjonalność do tego modułu lub rozbudować starą. W porównaniu do wprowadzania zmian w dobrze napisanym kodzie, takie zadania są bardziej prawdopodobne (i częściej przekraczają pierwotne szacunki) i zawierają więcej błędów. Czasem dużo więcej. Aby zabezpieczyć się przed tego typu problemami, staramy się planować refaktoryzacje tak, aby zostały wykonane przed napisaniem nowej funkcjonalności w tym samym miejscu.


Jeśli zmiany funkcjonalności i refaktoryzacje wydają się niewielkie, można je wykonać razem. Empirycznie wybrany rozmiar zadania, dla którego to podejście będzie optymalne, to 3 dni pracy na jednego programistę lub mniej. Kiedy już widać, że pracy jest więcej, dzieli się ją na refaktoryzację przy zachowaniu obecnego zachowania i wdrożenie nowej funkcjonalności.


Tym samym o kolejności prac mających na celu eliminację długu technicznego decyduje kolejność zadań biznesowych w backlogu.


Zasada „priorytetów biznesowych” ma jeszcze inne zastosowanie. Jednym z typowych problemów, na jakie cierpią programiści, którzy starają się dobrze pisać, jest trudność w poświęceniu czasu na optymalizację wydajności, poprawę łatwości konserwacji lub inne rzeczy, które nie są bezpośrednio uwzględnione w planie pracy. Prawie zawsze istnieje potrzeba biznesowa wprowadzenia tych ulepszeń. Kto nie chciałby, aby system działał szybciej, stabilniej i był tańszy w utrzymaniu? Wszystkie te korzyści można ocenić i na podstawie tej oceny można umieścić w backlogu zadania usprawnień wraz z innymi.


Jeśli więc chcesz zoptymalizować wydajność, ale zamiast tego musisz naprawić kolejny nudny błąd, być może po prostu nie wiesz, jak wyjaśnić korzyści płynące z optymalizacji w języku zrozumiałym dla właściciela produktu.

3. Pozostaw kod czystszy niż był przed tobą

Prawie każdy kod, z wyjątkiem tego, który powstał bardzo niedawno, pozostaje nieco w tyle za obecną koncepcją piękna w dziedzinie stylu i architektury. Kiedy w ramach zadania konieczna jest zmiana kodu, za dobrą praktykę uważa się wprowadzenie wszystkich możliwych ulepszeń w zakresie bezpieczeństwa w danym obszarze. Co to mogło być?

  • Doprowadzenie modułów do obecnego stylu.
  • Zmiana nazw zmiennych wewnętrznych na bardziej zrozumiałe.
  • Uprość wdrożenie, zachowując zachowanie.
  • Lokalne refaktoryzacje, które nie wprowadzają zmian na dużą skalę w innych modułach.

Oczekuje się, że te ulepszenia sprawią, że kod będzie lepszy, ale nie zwiększą znacząco kosztów programowania lub testowania.


Dzięki tej zasadzie jakość kodu stopniowo wzrasta w tle, nawet w tych miejscach, gdzie nie planowano osobnych refaktoryzacji. Co więcej, im częściej pracujemy nad daną częścią systemu, tym lepszy jest kod dla tej części. Miły kontrast w stosunku do projektów, w których programista spędza najwięcej czasu na częściach z najgorszym kodem.

4. Bez względu na to, co się stanie, system musi pozostać sprawny.

Jedna z podstawowych zasad SCRUM mówi, że na koniec każdego sprintu system powinien osiągnąć stan stabilny.


„Na koniec sprintu przyrost powinien być gotowy, czyli spełnia kryteria gotowości Zespołu Scrumowego i jest gotowy do użycia. Powinien być gotowy do użycia, niezależnie od decyzji właściciela produktu o jego udostępnieniu lub opóźnieniu.”

Wszelkie prace mające na celu eliminację długu technicznego prowadzone są zgodnie z tą zasadą.


Duże transformacje są koniecznie rozkładane, aby każdy pojedynczy etap można było ukończyć w jednym sprincie. Przykładowo zmieniliśmy system montażu w dwóch etapach ()


Współpracujemy z VCS według zasad bliskich klasycznemu gitflow. Rozwój odbywa się w gałęziach fabularnych, tam przeprowadzane są testy. Z reguły taka gałąź nie trwa dłużej niż jeden dwutygodniowy sprint. Oddział, który żyje dłużej, prawie zawsze wiąże się z dodatkowymi kosztami.


Nasze doświadczenie wyraźnie potwierdza tę prawidłowość. Za każdym razem, gdy nie udało nam się ukończyć dużej refaktoryzacji w ciągu dwóch tygodni, był to ból i cierpienie. Im dłuższe było zadanie i im dłużej żyła otwarta gałąź, tym wolniej szła praca i tym więcej było problemów.


Konieczność bycia zawsze kilka kroków od wydania stabilnego stwarza jeden z najtrudniejszych i najciekawszych problemów inżynierskich – znalezienie optymalnej dekompozycji planów strategicznych. Zmiany na dużą skalę można podzielić na osobne, niezależne etapy. Wskazane jest, aby rozpocząć pobieranie świadczeń jak najwcześniej. Im lepiej zostanie przeprowadzony ten podział pracy, tym większe są szanse na doprowadzenie zadania do końca.

Jak wygląda nasz proces

Raz na wydanie przeprowadzamy szczegółowy przegląd zaległości technicznych:

  • Zamykamy nieistotne historie (utracone znaczenie, utworzone jako część czegoś innego, duplikaty).
  • Aktualizujemy opis tam, gdzie zmieniła się wizja problemu.

Kiedy na horyzoncie pojawiają się historie biznesowe, przeprowadzana jest analiza techniczna i wszystkie historie techniczne, które pomogłyby we wdrożeniu, są kojarzone z historią biznesową.


W ramach przygotowań do planowania sprintu:

  • Sprawdzamy powiązania historii technicznej z biznesową.
  • Łączymy wszystkie powiązane błędy z historiami technicznymi, które można tanio naprawić w tym samym miejscu.

Jak utworzyć część techniczną backlogu

Kiedy objąłem rolę lidera zespołu, zapytałem każdego programistę i kontrolę jakości, jakie ulepszenia produktu najbardziej chcą wprowadzić. Większość zgłoszeń dotyczyła udoskonaleń technicznych platformy i refaktoryzacji. Jak pokazało dalsze doświadczenie, w tym zestawie życzeń uwzględniono wszystkie kluczowe problemy techniczne produktu. Można więc skorzystać z tej praktyki, aby szybko zbudować backlog techniczny od podstaw lub uzyskać ogólny pogląd na stan długu technicznego w nowym projekcie.


Bieżące zapełnianie backlogu zadaniami technicznymi następuje dzięki opisanym powyżej praktykom i nie wymaga odrębnych wysiłków ani analiz. Dodatkowo do backlogu dopisywane są nowe pomysły na techniczne udoskonalenie produktu. Robi to dowolny członek zespołu, który wpadł na taki pomysł. Najważniejsze na tym etapie to nie stracić pomysłu. Wyjaśnienie i określenie priorytetów następuje później, podczas planowania pracy.

wnioski

  • Dług technologiczny jest nieunikniony.
  • W przypadku większości projektów wyeliminowanie długu technicznego jest dobrą inwestycją wysiłku.
  • Jeżeli dług techniczny nie zostanie rozwiązany, tempo rozwoju będzie stopniowo zbliżać się do zera.
  • Pokusa wyrzucenia wszystkiego i napisania od nowa może zabić lub poważnie okaleczyć Twój projekt.
  • Korzyści z wyeliminowania długu technicznego należy ująć w kategoriach korzyści biznesowych, w przeciwnym razie istnieje ryzyko, że zadania tworzenia nowej funkcjonalności będą zawsze uważane za ważniejsze.
  • Zadaniami mającymi na celu eliminację długu technicznego warto się zająć. Zadania takie nie różnią się od innych zadań projektowych pod względem rachunkowości, planowania i ustalania priorytetów.
  • Regularnie pojawiają się sytuacje, w których można zmniejszyć dług techniczny i rozwiązać problem biznesowy jednocześnie taniej, niż robiąc to osobno. Należy wykorzystać te możliwości.
  • Przemyślane i terminowo aktualizowane konwencje dotyczące stylu kodu oraz procesy przeglądu pomagają spowolnić pojawianie się nowego długu technicznego.
  • Krótkie iteracje są równie przydatne przy refaktoryzacji, jak i przy opracowywaniu nowych funkcjonalności.
  • Zespół zazwyczaj wie, gdzie w projekcie znajduje się dług techniczny i jak bardzo jest on poważny. Tę wiedzę warto wykorzystać przy formułowaniu wyobrażenia o długu technicznym projektu.

KATEGORIE

POPULARNE ARTYKUŁY

2024 „kingad.ru” - badanie ultrasonograficzne narządów ludzkich