Przeczytaj wersję webową.

Szybko czy dobrze? Poproszę oba

2024-02-10

Cześć!

W dzisiejszym newsletterze chciałbym poruszyć problem, który nurtuje każdego lidera technicznego – na czym tak właściwie powinniśmy się skupiać w swojej pracy? Czy optymalizować się pod szybkie dostarczanie? Może pod wysoką jakość? A może istnieje jeszcze inne rozwiązanie?

Standardowo przygotowałem dla Ciebie również najświeższe informacje z branży produktów cyfrowych.

A więc w dzisiaj mam dla Ciebie:

Miłego czytania 😀


Inżynierska prasówka

W dzisiejszej czeka na Ciebie szeroki zakres tematów – od mocno technicznych, bo bardziej produktowe.

  1. Yes, good DevEx increases productivity. Here is the data. Eirini Kalliamvakou
    Bardzo kategoryczne stwierdzenie, ale autorka ma na nie twarde dowody. GitHub wraz z firmą DX rozpoczęli szeroki zakres testów, by potwierdzić (lub zaprzeczyć), że Developer Experience poprawia efektywność organizacji. I im się to udało: udowodnili znaczenie aspektów, które często są pomijane, a mają kluczowy wpływ na wydajność pracy. Także organizacje, pamiętajcie by dbać o pracę w flow, redukcję obciążenia kognitywnego i przyśpieszanie pętli feedbacku.
    https://github.blog/2024-01-23-good-devex-increases-productivity/

  2. Mastering Domain-Driven Desing Maciej Jędrzejewski
    Maciej pojawiał się już na łamach newsletteru kilka razy z tematami dookoła DDD. Ostatnio został również autorem konkretnej, nieprzesadnie długiej książki, która przystępnie wprowadza do tej tematyki. Od analizy domeny biznesowej, przez dzielenie na mniejsze obszary, aż po prace techniczne. Pozycja jest dostępna całkowicie za darmo, a to chyba uczciwa cena 😉
    https://www.fractionalarchitect.io/book

  3. Jakie narzędzia pomagają w budowaniu dokumentacji? Rafał Schmidt
    Nikt nie lubi dokumentować. Każdy za to lubi mieć już dobrze zbudowaną dokumentację. Rafał w swoim cyklu jej poświęconej, proponuje narzędzia, które ułatwiają budowanie zbioru wiedzy o systemie. Spójnie porusza się pomiędzy Mermaidem, GITem i modelem P3. Polecam też “przebić się” głębiej, do jego prezentacji podlinkowanej na stronie – pogłębia temat dokumentacji.
    https://rafalschmidt.com/jakie-narzedzia-pomagaja-w-budowaniu-dokumentacji/

  4. AB testing Bryan Finister
    Alan i Brent z podcastu Modern Testing zaprosili na swoje łamy Bryana – speca od Continuous Delivery. W efekcie powstała wciągająca rozmowa o tym, w jaki sposób optymalizować prędkość dostarczania, jednocześnie nie poświęcając jakości. A wręcz jak ją ulepszać. Sama rozmowa oparta na historiach z wdrażania praktyk CI/CD w Walmarcie. Jeśli macie godzinę czasu, to trudno lepiej ją wykorzystać.
    https://open.spotify.com/episode/4VJF6nXHVAFvszH8fiJAXU?si=CKnw36X_SR2aKfyjEIm5XA

  5. Understanding Architectures for Multi-Region Data Residency Alex Strachan
    Na koniec pozostawiam samo mięso techniczne. Alex opowiada o problemach i rozwiązaniach związanych z przechowywaniem i zarządzaniem danymi w systemach opartych o wiele regionów. Przekrojowo pokazuje złożoność dookoła aplikowania zmian w takiej architekturze. Pokazuje też architekturę, która jest w stanie takiemu wyzwaniu podołać. Jeśli masz problemy takiej skali to zdecydowanie polecam.
    https://www.infoq.com/articles/understanding-architectures-multiregion-data-residency/


Jak optymalizować naraz prędkość i jakość

W ramach wrocławskiego JUG wystąpiłem z prezentacją „Szybko czy dobrze – poproszę oba". Slajdy są dostępne na tablicy Miro.

Pomyślałem, że przybliżenie tego tematu tutaj będzie też dla Ciebie bardzo wartościowe.

Czy da się to w ogóle zrobić?

Wiele osób postrzega prędkość i jakość dostarczania jako dwie przeciwstawne krańce jednego wymiaru. Wybieramy albo skupienie się na tempie dostarczania, albo na efektach. Nic pomiędzy.

Może to wyglądać następująco:

IMG1.jpg

Takie podejście ma niestety pewne zasadnicze wady:

  • Zakładamy, że dbanie o jakość dzieje się kosztem prędkości.
  • Gdy prędkość dostarczania jest zbyt niska, łatwo poświęcamy jakość, bo jest zwyczajnie mniej widoczna.

Rozwiązaniem tej sytuacji nie jest wbrew pozorom optymalizacja ani w jedną, ani w drugą stronę. Trzeba zmienić perspektywę.

W książce The Software Architect Elevator, Gregor Hohpe mówi, że jedną z charakterystyk dobrego architekta jest myślenie wymiarami. I pokazuje to właśnie na przykładzie prędkości i jakości.

IMG2.jpg

Prędkość i jakość możemy postrzegać jako dwa przeciwne wymiary. Pomiędzy nimi zaś rozpościeramy krzywą naszej pracy w zespole. To na niej wybieramy, gdzie się znajdujemy – czy skupiamy się bardziej na tempie, czy rezultatach.

Ale ta zmiana pozwala nam to na o wiele więcej – widzisz już pojawiające się możliwości?

Zamiast przesuwać się po krzywej, możemy wykorzystać praktyki dostarczania, po zastosowaniu których ta krzywa będzie w innym miejscu.

IMG3.jpg

Dzięki tej zmianie, pojawia się pole na nowe pytania:

  • Jak dostarczać szybciej, wciąż z identyczną jakością?
  • Jak zwiększyć jakość, nie poświęcając przy tym prędkości?

To właśnie rozwiązaniom na powyższe będzie poświęcone 5 praktyk, które chciałbym Ci przybliżyć.

Nie ma Cię w newsletterze?
Zapisz się na radekmaziarka.pl

Szukanie wąskich gardeł

Aby poprawić prędkość, należy najpierw zrozumieć ona się rozkłada się w zespole. Rzadko kiedy problem leży w jednym obszarze pracy – zwykle jest rozłożony per cały proces dostarczania.

Mit: Liczy się moje tempo dostarczania

Prawda: Czas pracy nad zadaniem może być niewielki, a my i tak będziemy je dostarczać tygodniami.

Dla ułatwienia, warto to zwizualizować np. techniką Value-Stream Mappingu.

IMG4.jpg

Na diagramie widzimy:

  • Ośrodki pracy – jaskrawożółty kolor
  • Czasy pracy w ośrodku – jasnożółty kolor
    • CP – czas procesowania – uśredniony czas pracy nad jednym zadaniem.
    • CD – czas dostarczania – całkowity czas od podjęcia, do zakończenia zadania.
  • Kolejki – niebieski kolor
    • CK – czas, ile zadanie czekało średnio w kolejce.

Już po krótkiej obserwacji, możemy zauważyć, że:

  • Przeprocesowanie zadania trwa średnio 20 godzin.
  • Dostarczamy je 27 dni.
  • Efektywność procesu to 9% 😥

Na podstawie takiej analizy, możemy znaleźć dokładne lokalizacje, gdzie są wąskie gardła – to tam praca utyka i nie posuwa się dalej.

IMG5.jpg

To w tych miejscach nasze usprawnienia faktycznie podniosą efektywność procesu, nie obniżając jakości (a wręcz przeciwnie). W pracy produktowej, takimi obszarami nierzadko potrafią być:

  • Analiza wymagań
  • Pull Request Review
  • Górka testerska
  • Manualne potwierdzanie przez grono zarządzające
  • Ręczny deployment na produkcję

Ale oczywiście w twoim produkcie szkopuł może być w zupełnie innym miejscu.

Kolejna praktyka pozwala zaadresować odmienną część problemów dookoła wąskich gardeł.

Wdrażanie jakości od początku procesu

…czyli tzw. Shift Left Testing.

IMG6.jpg

W tej praktyce, wychodzimy ze stwierdzenia, że chcemy pamiętać o jakości na wczesnych etapach dostarczania, aby późniejsze braki nie wstrzymywały nam pracy.

Mit: Jakość może być punktem w procesie.

Prawda: Gdy jakość jest punktem w procesie, to jej zapewnianie zajmuje bardzo dużo czasu i ostatecznie ludzie porzucają jakość kosztem prędkości.

Dlatego należy wdrażać jakość na każdym etapie dostarczania. Dzięki temu unikamy powrotów do poprzednich stadiów pracy. A to owocuje w wyższej jakości bez straty prędkości.

Na każdym etapie pracy mamy do dyspozycji różnorodne metody dbania o jakość:

  • Analiza wymagań – określanie scenariuszy użycia i przypadków brzegowych, odrzucanie scenariuszy, na które na razie się nie decydujemy czy definiowanie przypadków do przetestowania na każdym poziomie piramidy.
  • Projektowanie – wstępne projektowanie, w ramach którego będziemy sprawdzali, czy obsługujemy scenariusze użycia, określali ryzyka.
  • Development – automatyzujemy na jak najwcześniejszym etapie prac, pracujemy wspólnie z inżynierem jakości, aby od razu wyłapywać błędy.
  • Deployment – określamy wymagane klucze i parametry, definiujemy ścieżki i warunki promowania na kolejne środowiska.

Praca w małych partiach

Chcąc dostarczać szybko, jakościowo i do tego oba naraz, musimy się skupić na zmniejszaniu wielkości pojedynczego projektu / zadania.

Mit: Nie ma znaczenia czy projekt jest duży czy mały, bo sumarycznie wychodzi na to samo.

Prawda: Przy większych projektach ilość powiązań wewnętrznych zwiększa się wykładniczo, a nie liniowo, co skutkuje wydłużeniem czasu dostarczania i mniejszym skupieniem na jakości.

IMG7.jpg

Praca w małych partiach pozwala na:

  • Łatwiejsze utrzymywanie jakości.
  • Zmniejszenie ryzyka wpływu zmiany na obecne rozwiązanie.
  • Rozpoczynanie dostarczania od najważniejszych celów / jakości.

Jak się do tego zabrać?

Czysto technicznym rozwiązaniem jest zmniejszenie kosztu transportu:

IMG8.jpg

Często zdarza się tak, że sama funkcja może być mała, ale za to wszystko dookoła trwa i kosztuje dużo. Wtedy nikt nie będzie dostarczał małymi partiami, bo to się nie będzie po prostu opłacało.

W kolejnych krokach można się zastanowić jak pracować wertykalnie, zamiast poziomo. Tutaj przydaje się świetna wizualizacja od Gojko Adzica:

IMG9.jpg

Staramy się wypracowywać takie rozwiązania na wielu warstwach technicznych tak, aby dowieźć minimalny zakres biznesowy. Dzięki temu dostarczamy wartość szybko i możemy iterować z kolejnymi wymaganiami.

Pomaga również skupienie się na wydzieleniu wszystkiego co nie musi wyjść w pierwszym wdrożeniu – bardzo przyjemnie się przeprowadza taką dyskusję mając wizualny proces na bazie Event Stormingu:

  • Główna funkcja, a efekt uboczny – wysłanie maila podsumowującego po zamówieniu możemy zrobić w kolejnym kroku.
  • Reguły walidacyjne – na początku niekoniecznie potrzebujemy sprawdzania wszystkich reguł.
  • Negatywne scenariusze użycia – można je zatrzymać przez proste wyświetlenie, że tego scenariusza na razie nie realizujemy.

Stopniowe wdrażanie

Nie zawsze można ograniczyć rozmiar partii – biznes potrzebuje dostać skończoną funkcję do wykorzystania. Ale to nie oznacza, że my musimy ją wdrożyć na big-bang.

Mit: Jak wdrażam, to od razu musi być widoczne dla wszystkich.

Prawda: Można oddzielić wdrożenie od samego uruchomienia, by wdrażać częściej niż uruchamiać.

Świetnie to przedstawia Hiren Dhaduk w swoim artykule Deployment vs. Release:

IMG10.jpg

Dzięki takiemu podejściu możemy uniezależnić wdrożenie od uruchomienia. To nam pozwala połączyć kilka wdrożeń w jedno uruchomienie. Ale, przede wszystkim, pozwala potwierdzić jakość wdrożenia dla małej, atomowej zmiany. Dzięki czemu szybciej poprawiamy błąd i unikamy degradacji jakości.

Typowym rozwiązaniem tutaj są Feature Toggles / Feature Flags o których przekrojowo pisze Pete Hodgson:

IMG11.jpg

Jesteśmy w stanie przetestować zmianę flagując daną funkcję. To pozwala sprawdzić w małej skali, jak się ona zachowuje i poprawiać już przy kolejnych wdrożeniach.

Innymi, wartymi uwagi metodami są:

  • Dark Launching – Wdrażana funkcja jest uruchamiana, ale jej wyniki są ignorowane.
  • Keystone Interface – Wdrażana funkcja działa na produkcji, ale nie wykonuje widocznych zmian dla użytkownika.

Ciekawą opcją, choć jednocześnie ciężką do zrozumienia jest Canary Release:

IMG12.jpg

Chcemy zacząć od uruchomienia funkcji dla małej grupy użytkowników. Będziemy ją dalej otwierać, gdy potwierdzimy, że działa odpowiednio. Dzięki temu testujemy wdrożenie na małej, ale jednocześnie produkcyjnej grupie. Z jakiego powodu wydaje się to niezrozumiałe? W większości przypadków, by tak robić, nie potrzebujesz ogromnej architektury, Load Balancera itd. Można taki schemat wprowadzić nawet na przykładzie Cookies, które wysyłasz danemu rodzajowi klientów. I początkowo nawet ta grupa 1% będzie już korzystała z nowego API.

Ograniczanie pracy w toku

Chcąc dostarczać szybko, musimy się skupić nad tym, by nie żonglować naraz 20 piłeczkami.

Mit: Niezależnie, ile zadań mam aktualnie otwartych, praca nad całością będzie trwała tyle samo.

Prawda: Duża ilość zadań powoduje, wzrost kosztu przełączania się, kognitywne zależności, które opóźniają twoje wdrożenia.

Im mamy mniej pracy w toku, tym łatwiej jest uniknąć tworzenia się wąskich gardeł w procesie. Jesteśmy w stanie dostarczać najważniejsze zadania najpierw. Zmniejszamy w ten sposób stratę, przez rewrite’y zależnych od siebie funkcji. Same plusy!

Pierwszym sposobem rozwiązania tego problemu jest sterowanie pracą od przodu tzw. Pull system:

IMG13.jpg

Na podstawie obecnego obłożenia ośrodka pracy, określamy przy jakiej liczbie prędkość dostarczania zaczyna gwałtownie spadać. Z tą perspektywą z tyłu głowy, określamy ośrodkowy limit pracy. Kiedy tylko zostanie osiągnięty, dostaniemy informację, aby nie dorzucać więcej zadań. Praca utknęła na kolejnym etapie, musimy więc skupić się na wąskim gardle.

Innym rozwiązaniem jest skupienie się na końcu procesu dostarczania. Chcąc kończyć pracę, zamiast od nowa rozpoczynać, powinniśmy wykorzystać okazje takie jak daily, aby sobie zadać pytania w stylu:

  • Czego mi brakuje, aby skończyć to zadanie?
  • Jak wiele mniejszych zadań nie jest jeszcze zrealizowanych?
  • Kto mi może w tym pomóc? Może nawet częściowo?

Dzięki wyjaśnieniu tych kwestii, zamiast brać się za nową robotę będziemy starali się wzajemnie sobie pomagać w domykaniu tematów. Dobrym pomysłem jest także zrównoleglanie pracy nad jednym projektem, zamiast rozgrzebywania wszystkich naraz:

IMG14.jpg

Dzięki temu powiązane ze sobą zadania są realizowane w tym samym oknie czasowym, co ułatwia współpracę pomiędzy obszarami. Unikamy też przerzucania problemów “przez płot” i nie musimy wiecznie się zastanawiać o co chodziło tej drugiej osobie.

Pomaga również migracja osób pomiędzy ośrodkami pracy:

IMG15.jpg

W przypadku wąskiego gardła zwykle możemy wydzielić zadania na tyle nieskomplikowane, że spokojnie możemy je oddelegować. I być może pomóc będzie w stanie nawet osoba, która nie jest w temacie ekspertem. Dzięki między obszarowemu podejściu do pracy, rośnie zrozumienie zespołu nad tematami crossfunkcyjnymi. A to ostatecznie pozwala łatwiej współpracować i ograniczać pracę zawieszoną w toku.

Podsumowanie

Zgadza się, prędkość i jakość da się optymalizować jednocześnie. Jednak, aby to osiągnąć, musimy zaprzęgnąć do pracy praktyki wychodzące poza prosty kompromis A vs B. Mam nadzieję, że przedstawione powyżej praktyki pozwolą Ci to osiągnąć.

A Ty, znasz jeszcze jakieś praktyki optymalizacji pracy w zespole?


📧 Prześlij dalej

Dzięki, że doczytałeś(aś) do końca. 😊

Wszystkie poprzednie wydania newslettera są dostępne tutaj.

Jeśli spodobał Ci się mój newsletter, prześlij go proszę osobom, którym też mógłby się spodobać. Z góry dziękuję.

A jeśli nie jesteś jeszcze w newsletterze, to zachęcam do zapisania się.

Polecam się na przyszłość!
Radek Maziarka

Radek Maziarka
"Inżynierskie podejście do produktów cyfrowych."

P.S. Co myślisz o tym newsletterze? Odpisz :)