Przepisanie aplikacji – wyzwania, narzędzia i dobre praktyki

Przepisanie aplikacji

We współczesnym świecie technologia IT nie tylko odgrywa bardzo ważną rolę w życiu każdego człowieka, ale również bardzo szybko się zmienia. Zmiany w aplikacjach dzielą się na funkcjonalne, czyli takie, które są bezpośrednio widoczne przez użytkownika końcowego i wpływają na jego korzystanie z aplikacji, dostarczając mu nowych rozwiązań i możliwości, na przykład umożliwienie płatności kartą kredytową, dodanie bardziej zaawansowanych opcji filtrowania czy dodawanie produktów do listy ulubionych oraz niefunkcjonalne: szybkość zapisywanie informacji do bazy danych, zabezpieczenie aplikacji czy zmiana architektury i technologii w jakim jest napisana. 

Przepisanie aplikacji – od czego zacząć?

W tym artykule podzielę się z Wami moimi doświadczeniami z projektu, którego celem było przepisanie aplikacji obecnie działającej na środowisku produkcyjnym, natomiast jej aktualna architektura oraz technologia nie pozwalają na szybkie skalowanie aplikacji na wielu klientów, przy tym czas implementacji zmian jest zbyt długi. Dodam, że naszymi klientami są firmy, które wykonują kilkaset skomplikowanych operacji w ciągu godziny, generując olbrzymią liczbę danych, wykorzystywaną równolegle przez setki operatorów.

Wystartowanie takiego przedsięwzięcia, jakim jest przepisanie aplikacji, generuje wśród programistów burzę pomysłów, a co za tym idzie chaos, nad którym project manager powinien zapanować. Dostaliśmy zadanie do wykonania, jednak decyzja co do sposobu realizacji została pozostawiona nam. I tu na szali stanęły dwa podejścia:

  • ewolucyjne – przepisanie aplikacji następuje małymi krokami, sukcesywnie podmieniamy zmiany na produkcji,
  • rewolucyjne – nie ingerujemy w aktualne rozwiązanie, piszemy nowy software od zera i dopiero po ukończeniu developmentu wygrywamy go na produkcję.

Rozpoczął się proces analizy obydwu rozwiązań pod kątem ich efektywności kosztowej, czasowej i ryzyk z nimi związanych. Stojąc na czele dwóch zespołów biorących w niej udział, postanowiłem wprowadzić dobre praktyki, które pozwoliły poukładać działania oraz skierować zaangażowanie zespołów w jednym kierunku:

  • poznanie produktu, 
  • zdefiniowanie zakresu MVP,
  • stworzenie Proof of Concept,
  • stworzenie rejestru ryzyk, zależności i założeń,
  • wysokopoziomowe estymowanie prac,
  • plan wdrożenia na produkcję,
  • wybór narzędzi wspierających projekt.

Spostrzegawcze osoby zauważą, że łączę praktyki agile’owe z waterfallowymi, aby osiągnąć najlepsze wyniki.

Poznanie produktu

Napisanie dobrego produktu to nie tylko ładny UI (ang. user interface), ale również przemyślana architektura aplikacji. Pytanie co zrobić, żeby ta niewidoczna część była zaplanowana jak najlepiej oraz odpowiadała teraźniejszym jak i przyszłym wymaganiom biznesowym? Jednym z dobrych podejść do szybkiego, a zarazem dobrego stworzenia produktu jest poznanie go na żywo, pracowanie z użytkownikami naszego systemu ramię w ramię, rozmowa z nimi oraz managerami, którzy na co dzień wykorzystują aplikację. Oto, co można od nich zebrać:

  • lista rzeczy, które są dobrze przyjmowane przez użytkowników, 
  • obszary aplikacji, które nie są wykorzystywane,
  • funkcje, które mogłyby być naprawione w przyszłości (przy okazji pisania nowego rozwiązania). 

Może ciężko będzie Wam uwierzyć, ale rezultaty takiego ćwiczenia były dla nas zaskakujące – nagle okazało się, że spora część rozwiązań była z punktu widzenia ich użytkowników niepotrzebna. Co więcej, okazało się, że system, który powinien wspierać działania pracowników, przeszkadza im i pracownicy sami nauczyli się obchodzić system, aby pracować efektywniej. 

Wszystkie te informacje podczas poznawania systemu warto udokumentować w postaci pisemnej, zdjęć czy też filmików, a następnie udostępnić w jednym miejscu. Ja wybrałem i polecam Wam narzędzie miro.com, które pozwoli zarówno na zilustrowanie procesów, odwzorowanie diagramów przepływu, zależności, wrzucanie zdjęć oraz – co ważne – współdzielenie pomiędzy różnymi osobami.

Zdefiniowanie zakresu MVP

Przygotowanie backlogu produktowego pod MVP (ang. Minimum Viable Product, w tłumaczeniu Minimalnie Opłacalny / Satysfakcjonujący / Możliwy Produkt to wersja produktu, która minimalnym wysiłkiem zapewnia wystarczające rozwiązania, aby zadowolić pierwszych klientów i przekazać opinie na temat przyszłego rozwoju produktu), w naszym gronie nazywanym “wydmuszką”, było pierwszym zadaniem, do którego przystąpiliśmy po poznaniu produktu. 

Nasze MVP posiadało podstawowy zbiór rozwiązań potrzebnych do uruchomienia naszej nowej aplikacji na produkcji, a co za tym idzie, uświadomiło całemu zespołowi jakie obszary aplikacji są kluczowe i należy na nie zwrócić szczególną uwagę podczas implementowania naszej przyszłej architektury. 

Podczas wypracowywania zakresu MVP oraz, mając na uwadze, że w najbliższych tygodniach startujemy z PoC (ang. Proof of Concept, tłum.: weryfikacja słuszności konceptu), zorganizowaliśmy serię spotkań z przedstawicielami obecnego rozwiązania, aby dowiedzieć się więcej na temat związanych z nim problemów oraz usłyszeć o błędach, które zostały popełnione i warto ich unikać, gdy nastąpi przepisanie aplikacji. Taki wkład zarówno z punktu deweloperskiego jak i produktowego pozwolił zespołom na przystąpienie do pracy nad PoC.

Stworzenie Proof of Concept

Przed rozpoczęciem pracy nad właściwym produktem zaproponowałem podzielenie prac na 3 etapy: 

  1. PoC (proof of concept), 
  2. MVP (ang. Minimum Viable Product) – jest to aplikacja, która posiada minimalny zbiór rozwiązań potrzebnych do uruchomienia produkcyjnego,
  3. Rozwój produktu – etap, w którym będziemy pracować nad rozwojem aplikacji o funkcje wymagane przez biznes. 

Stworzenie dobrej architektury przyszłej aplikacji jest bardzo ważne i tak naprawdę prawdziwe korzyści można czerpać w momencie, gdy aplikacja jest już wdrożona na produkcje a od strony biznesu przychodzi zapytanie o zaimplementowanie nowej funkcjonalności. Tak naprawdę wtedy widać, czy architektura aplikacji została przemyślana i jak łatwo można między innymi:

Aby nabrać pewności co do słuszności naszego rozwiązania i uniknięcia zmiany podejścia przy pisaniu wersji produkcyjnej, zdecydowaliśmy się na trwający miesiąc proof of concept.

Co tak naprawdę zrobiliśmy? W ramach z góry zdefiniowanego czasu deweloperzy wypracowali najlepsze rozwiązanie architektoniczne, dzieląc całą aplikację na kilka modułów oraz obszarów odpowiedzialności. Sama architektura to nie wszystko. Podczas wypracowywania architektury postanowiliśmy przetestować i zintegrować różne narzędzia np. do wgrywania kodu lub monitorowania aplikacji. Na rynku jest ich wiele, każde oferuje wachlarz możliwości, dlatego przetestowanie wybranych narzędzi pozwoliło nam wybrać te, z których chcemy skorzystać. 

Jak wyglądał wybór narzędzi i finalnej wersji diagramu? Po zakończeniu PoC zorganizowaliśmy spotkanie, gdzie wykorzystaliśmy podejście Lean Coffee Retro i “metodę kciuków” (kciuk do góry – jestem na tak, kciuk w bok – nie mam zdania, w dół – jestem na nie). Wybraliśmy najlepsze narzędzia oraz finalną architekturę aplikacji. Wszystkie uzgodnienia zostały udokumentowane w postaci diagramu architektury (u nas przy pomocy draw.io) oraz przepływów najważniejszych procesów biznesowych (wykorzystaliśmy sequencediagram.org).

Stworzenie rejestru ryzyk, zależności i założeń

Praca przy nowym projekcie wiąże się z wieloma wyzwaniami i problemami, które w początkowej fazie, w przypływie emocji na myśl, że coś nowego się zaczyna, mogą zostać pominięte. Przed podjęciem konkretnej decyzji co do sposobu realizacji projektu, stworzyłem: 

  • rejestr ryzyk oparty o ich jakościową analizę,
  • zależności od innych zespołów,
  • rejestr założeń.

Analiza ryzyk miała na celu zachęcenie do dyskusji i przewidzenie potencjalnych szans i zagrożeń jakie niesie przepisanie aplikacji, a które będziemy mogli wykorzystać lub starać się unikać. Jedno z ważniejszych zagrożeń, które udało nam się wówczas zidentyfikować związane było z nieudanym wdrożeniem produkcyjnym, które (w razie wystąpienia) wstrzymałoby najważniejszy proces w firmie, co znów niosłoby ze sobą ogromne straty finansowe. Identyfikacja ryzyk jest jednoczesnym zaproszeniem do rozmowy w celu wypracowania najlepszego planu działania. Nam pomogła podjąć również decyzję co do sposobu realizacji produktu – wygrało podejście ewolucyjne.

Lista zależności miała na celu zidentyfikowanie zadań, których wykonanie będzie leżało po stronie innych zespołów. Warto się z nimi poznać i porozmawiać z wyprzedzeniem. Dzięki temu poznaliśmy ich oczekiwania, a także ich podejście do współpracy. Nauczony na własnych błędach wiedziałem, że ciężko będzie poprosić o znalezienie wolnego czasu w innych zespołach, gdy przyjdę do nich z informacją, że potrzebujemy czegoś na jutro. Każdy zespół ma swoje plany i listę priorytetów, którymi się kieruje, dlatego warto zadbać o to, aby te zależności były znane i uwzględnione w pracy obydwu stron. 

Stojąc przed decyzją wyboru podejścia między ewolucyjnym a rewolucyjnym, dokonaliśmy również kilku założeń, które miały nam ułatwić wybór decyzji. Naszym celem było wybranie lepszego rozwiązania, zarówno pod względem architektury kodu jak i szybkości dostarczenia. Dokonując porównania w pierwsze fazie przyjęliśmy następujące założenia: 

  • projekt otrzyma nową infrastrukturę, która pozwoli na szybkie testowanie nowego rozwiązania,
  • do zespołu włączone zostaną dodatkowe 2 osoby odpowiedzialne za testowanie aplikacji oraz jedna osoba odpowiedzialna za produkt,
  • projekt ze względu na swój wysoki priorytet dostanie wsparcie od innych zespołów i nie będzie zablokowany przez zewnętrzne zespoły.

Wysokopoziomowe estymowanie prac

Estymowanie prac, szczególnie w nowych projektach, gdzie wiedza jest niekompletna, a potencjalne ryzyka z punktu biznesowego i technologii są nie do końca znane, jest niewątpliwie trudne. Z własnego doświadczenia wiem, że najgorzej jest zacząć. Przygotowanie zgrubnej estymaty po zakończonym PoC było dla zespołu dużo łatwiejsze. W tym czasie lepiej poznaliśmy aktualny produkt zarówno z punktu technicznego – przeglądając kod aktualnego rozwiązania, jak i z punktu widzenia biznesowego – pracując z użytkownikami końcowymi. 

Zaczęliśmy od listy funkcji biznesowych, którą przygotował nam Product Owner. Każdy z elementów listy posiadał jasno zdefiniowane wymagania, które powinny zostać spełnione. Każdy z kolejnych obszarów miał nas doprowadzić do zbudowania finalnej wersji MVP, a w późniejszym czasie dostarczenie brakujących funkcjonalności znajdujących się w aktualnym rozwiązaniu. 

Podeszliśmy do estymaty zgrubnie, wiedzieliśmy, że szacowanie pracy, jaką jest przepisanie aplikacji, w godzinach się nie sprawdzi (za duża dokładność) tak samo jak metoda porównawcza – nie mieliśmy do czego porównywać, nasze doświadczenie w nowej domenie było niewielkie. W tym wypadku zastosowaliśmy estymatę w tygodniach. Jednostka ta pozwoliła nam rozwiązać problem z dokładnością estymowanych zadań, uwzględniając fakt, że mamy relatywnie duża niewiedzę w tym temacie oraz wyeliminować dużą rozbieżność szacunków pomiędzy członkami zespołu.

Plan wdrożenia na produkcję

Przepisanie aplikacji wiąże się z podmianą kodu produkcyjnego i jest wyzwaniem dla zespołu deweloperskiego nawet w sytuacji, gdy logika biznesowa nie uległa zmianie, czyli użytkownik końcowy nie zauważy żadnych różnic w działaniu aplikacji po wgraniu nowego kodu. Pewnie wiele osób zastanowi się dlaczego? W naszym przypadku powodów było kilka, między innymi:

  • Nowy kod, mimo przetestowania, może posiadać błędy, które spowodują zablokowanie stanowiska pracy dla kilkuset pracowników, a co za tym idzie – wygeneruje olbrzymie straty finansowe, dlatego przy dużych aplikacjach używanych produkcyjnie przez setki osób nie podmienia się całego oprogramowania jednocześnie. Najczęściej podmienia się software częściowo, kawałek po kawałku tak, aby było łatwo zidentyfikować potencjalne problemy. Znalezienie błędu w mniejszym wycinku nowo wgranej aplikacji jest dużo łatwiejsze, niż szukanie dziury w przypadku wgrania całości aplikacji jednocześnie.
  • Podczas wgrywania nowego oprogramowania konieczna była synchronizacja pomiędzy wieloma zespołami pracującymi w różnych lokalizacjach. Działanie takie wymagało dwutygodniowych przygotowań, aby przestój na produkcji był praktycznie niezauważalny.
  • Musieliśmy opracować scenariusz, gdy coś pójdzie nie tak, tj. przygotować rollback plan (plan wycofania zmian i przywrócenia starej wersji systemu).

Znając wszystkie ograniczenia i obszary, które potencjalnie mogą nie zadziałać, zabrałem się za rozmowę z managerami, którzy odpowiedzialni są za codzienne zarządzanie aplikacją na produkcji. Przygotowując plan wdrożenia, chciałem poznać również zdanie operatorów, bo tak naprawdę to oni codziennie współpracują z ludźmi na produkcji, znają ich zwyczaje i wiedzą, jaki moment będzie właściwy na nasze działania. 

Po wielu dyskusjach zarówno z managerami w magazynie, jak i programistami z innych zespołów przyjęliśmy “kanarkowe wydanie” aplikacji (ang. canary deployment). Idea ta pozwala na procentowy podział ruchu klienckiego pomiędzy dwie aplikacje: stara i nową, co pozwoliło nam na powolną weryfikację naszego konceptu na “żywym organizmie” z ograniczonym ryzykiem.

Wybór narzędzi wspierających projekt

Wystartowanie nowego projektu z dobrze znaną grupą ludzi generuje nowe wyzwania, które wcześniej się nie pojawiały – o nich też chciałbym opowiedzieć. Przepisanie aplikacji wymaga nie tylko przygotowanie dobrej architektury, ale również – jak każdy nowy projekt – przygotowania narzędzi pomocniczych, które będą wspierały efektywną komunikację w zespole. Mam na myśli stworzenie kanałów komunikacji, zorganizowanie tablicy w Jirze, wspólnego miejsca do dokumentowanie najważniejszych decyzji i przetrzymywania zdjęć, diagramów oraz wypracowania procesów w zespole. Wszystkie zmiany zarówno w narzędziach jak i procesach, których dokonywałem, były wcześniej uzgodnione i przedyskutowane w zespole. Wychodzę z założenia, że procesy są dla ludzi, a nie ludzie dla procesów, dlatego też eksperymentowaliśmy, weryfikując, które podejście będzie dla nas najlepsze. Na przykład:

  • Śledzenie postępów w procesie przeglądu kodu zmieniało się wiele razy: zaczęliśmy od zdefiniowania liczby osób, które powinny przeglądnąć zmianę zanim zostanie zaakceptowana, poprzez sposób korzystania z narzędzi, które pokażą nam aktualny status. I tak na przykład podczas Daily Scrum przeglądaliśmy status w Crucible (narzędzie do przeglądu zmian w kodzie), a skończyliśmy na kolumnie “Review” w Jirze. 
  • Zaczęliśmy monitorować dostępność naszych pracowników przy pomocy wspólnego ogólnie dostępnego w zespole kalendarza Google. Działanie to pozwoliło nam w łatwy sposób zidentyfikować osoby, które są na urlopie, pracują zdalnie lub są na szkoleniu, a dzięki dodatkowej wtyczce na Slacku, codziennie rano dostawaliśmy informacje o dostępności poszczególnych członków zespołu.
  • Zainaugurowaliśmy zbieranie feedback’u od członków zespołu przy pomocy Kudobox. Było to zwykłe papierowe pudełko przypominające urnę, gdzie każdy z członków zespołu mógł wrzucić karteczkę ze swoją uwagą, pomysłem lub podziękowaniem. Intencją tego działania było zebranie nowych pomysłów w zespole – wiele inicjatyw przychodzi nam do głowy, ale gdy nie zostaną szybko zapisane, przepadają. Chciałem, żeby dobre pomysły zostawały z nami, a problemy były zauważane i dyskutowane na bieżąco, dlatego do Kudobox’a trafiały też bolączki zespołu.
  • Wykorzystaliśmy również wtyczkę napisaną na nasze potrzeby, którą można zintegrować z przeglądarką Chrome i repozytorium danych. Pozwala zapisywać wszystkie podstawowe linki w jednym miejscu i w łatwy sposób wyświetlić ją na pasku przeglądarki. Tym sposobem każda nowa osoba w projekcie może dodać je do swojej przeglądarki. Być może znajdziecie jakiś rynkowy odpowiednik (przyznaję – ja nie szukałem).

Na zakończenie

Jak widzicie przepisanie aplikacji to specyficzny rodzaj projektu, który – ponieważ wiąże się z podmianą rozwiązania działającego produkcyjnie – wielu przyprawia o siwe włosy i stres. Jak w każdym projekcie i tu clue sukcesu jest dobre przygotowanie się. Mam nadzieję, że przedstawione przeze mnie praktyki oraz narzędzia pomogą również Wam. 

Na końcu chciałbym wspomnieć jeszcze o jednym elemencie tej całej układanki, dzięki któremu udało nam się osiągnąć tak dobre rezultaty – to ludzie. To dzięki nim, ich zaangażowaniu i otwartości na eksperymenty mogliśmy dokonać tylu zmian. W dzisiejszych czasach programowanie przestaje być wiedzą tajemną i coraz bardziej docenia się umiejętność pracy w zespole.

Jeżeli masz jakieś pytania do tego, co napisałem, zostaw komentarz lub pytanie – odpowiem :) 

Zdjęcie: https://pl.freepik.com/

Więcej wpisów autora: Maciej Bieniasz

Rozproszone zespoły – jakie wyzwania stawiają przed managerem?

W dzisiejszych czasach w świecie IT panuje bardzo duża rywalizacja. Każda firma...
Czytaj dalej

2 komentarze

  • ”nagle okazało się, że spora część rozwiązań była z punktu widzenia ich użytkowników niepotrzebna” – haha absolutnie nie ciężko w to uwierzyć, natomiast pojawia się pytanie o lessons learned z poprzedniego wdrożenia, o dyskusję z Product Ownerem odnośnie bieżącego zarządzania i postawienia wymagania jedynie co do skalowalności aplikacji i lessons learned po obecnym projekcie. Szacunek za podejście do analizy ryzyka;)

    • Łukasz,
      lessons learned w wielu firmach jest jak Yeti – każdy słyszał, nikt nie widział Możemy nad tym ubolewać lub dołożyć swoją cegiełkę do zwiększania świadomości w tym obszarze, co też czynimy
      Pozdrawiam,
      Maciej

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *