Author

Jakub Kubryński

Browsing

Każdy z nas chce być szczęśliwy. Jednak czy da się zmierzyć szczęście? Czy możemy z pełnym przekonaniem stwierdzić, o ile jesteśmy szczęśliwsi danego dnia? Czy ktokolwiek usłyszał „dzisiaj jestem o 10% bardziej szczęśliwy niż tydzień temu”? Szczerze wątpię, jednak jeśli nawet, to czy miałoby to jakikolwiek sens? Nikt przecież nie oczekuje matematycznego podejścia do uczuć. Inaczej natomiast wygląda to w przypadku oprogramowania.

Eksperckie przeczucia

Sukces da się zmierzyć liczbami. A wszyscy, którzy twierdzą inaczej po prostu boją się prawdy.

Jo Nesbo

Tu równie często spotykam się z bardzo luźnym podejściem, „na czuja”, zamiast operowania twardymi liczbami. A mogłoby się wydawać, że to właśnie liczby powinny być naturalnym sposobem komunikacji w świecie technologii.

Szkolenia z architektury systemów często rozpoczynam od pytania: co rozumiemy przez „dobrą architekturę”? Jakie cechy świadczą o tym, że jest ona właściwa? Zazwyczaj odpowiedzi uzależnione są od profilu konkretnej firmy. Kilka z nich jednak się powtarza i ustalamy, że architektura powinna być:

  • utrzymywalna,
  • elastyczna,
  • dopasowana,
  • testowalna,
  • bezpieczna.

Gdy mamy już gotową listę, proszę o zapisanie na kartkach definicji jednej z powyższych cech, np. testowalności. Następnie każdy czyta swoją definicję i z każdą kolejną wypowiedzią rośnie konsternacja.

„Testowalność oznacza możliwość weryfikacji każdego komponentu systemu”

„Testowalność osiągamy przez krótki czas wykonania testów”

„Testowalność rozumiemy jako wysoki procent pokrycia kodu testami automatycznymi”

Co się stało? Chwilę wcześniej wszystko było uzgodnione, a teraz pojawiły się rozbieżności. I całe szczęście, że wydarzyło się to w kontrolowanych warunkach, podczas szkolenia, a nie kiedy wszyscy już wrócili do pracy. Wtedy skończyłoby się na tym, że jeden zespół dodaje testy, aby zwiększać pokrycie, a drugi je usuwa, byleby kompilacja odbywała się tak szybko, jak wcześniej. I konflikt gotowy. A wystarczyło wyrównać poziom świadomości.

Wyrównywanie poziomu świadomości

Do takiej operacji uspójniania oczekiwań możemy wykorzystać liczby. Uzgodnienie skali (bądź też skal) danej cechy, ujednolica jej rozumienie. Przeanalizujmy poniższe przykłady:

„Czas w minutach potrzebny do wykonania testów automatycznych na środowisku ciągłej integracji”

„Procent ścieżek krytycznych pokrytych testami end2end”

„Liczba funkcjonalnych błędów blokujących wykrytych na środowisku produkcyjnym”

„Procent procesów biznesowych możliwych do przetestowania akceptacyjnie bez wykorzystania GUI”

Oczywiście skale te bardzo się między sobą różnią. Ciężko wypracować „jedyną słuszną” definicję jakiejś cechy. Zawsze zależy ona od technologii (będzie inna dla aplikacji web i systemów embedded), stanu projektu (właśnie startuje czy jest rozwijany od 12 lat) czy też oczekiwań klienta (safe to fail czy fail-safe). Ważne jest jednak, że w obrębie jednej grupy ludzi dane zagadnienie rozumiane jest jednoznacznie.

Metryki

Skoro mamy już skale, możemy pójść krok dalej i zdefiniować metryki. Zazwyczaj określamy trzy wartości: obecną (current), cel (goal) oraz znakomitą (wish) . Dla czasu wykonania testów może to być np.:

  • wartość aktualna = 8 minut
  • cel = 6 minut
  • wartość znakomita = 4 minuty

Mierząc zmiany wartości metryki, widzimy, w jakim kierunku zmierza nasz projekt i na ile udało nam się osiągnąć założone cele. Doszliśmy zatem do poziomu, w którym możemy śmiało powiedzieć, że zgodnie z naszą definicją „po ostatnich zmianach aplikacja jest o 21% bardziej testowalna”. Już nie „przeczucia”, a liczby świadczą o właściwej bądź niewłaściwej realizacji zadań. Powoduje to też wzrost przejrzystości naszej pracy w oczach biznesu (czyli naszego klienta). Przenosi nas z poziomu „zawsze coś tam dłubiecie i refaktoryzujecie” do poziomu „Wasza praca ma teraz mierzalne efekty”.

A jakie są Wasze doświadczenia z metrykami? Zachęcam do podzielenia się nimi w komentarzach.

Seria strategicznych gier Cywilizacja słynie między innymi z bardzo rozbudowanych drzew technologii. Są one ze sobą ściśle powiązane i na przykład, żeby móc budować statki, trzeba wcześniej zgłębić tajniki matematyki i astronomii. Odkrycie nowej technologii otwiera przed nami kolejne możliwości rozwoju naszej cywilizacji. To właśnie ta możliwość, wszechstronnego i jasno określonego rozwoju, jest jedną z głównych sił napędowych popularności serii.

Grupą podobnie zafascynowaną rozwojem jak gracze, są programiści. Ponieważ obecnie coraz trudniej znaleźć na rynku tych dobrych, rekruterzy używają coraz lepszych farb do malowania trawy na zielono. Działy HR prześcigają się we wprowadzaniu kolejnych benefitów. Z drugiej strony jednak, mało kto głęboko zastanawia się nad realnymi potrzebami programistów. A grupa ta przede wszystkim chce poznawać nowe technologie, podejmować ciekawe wyzwania i dzielić się wiedzą.

Czemu w takim razie większość firm oferuje jedynie utartą ścieżkę kariery, w której powyżej poziomu senior developera można rozwijać się tylko w kierunkach managera, architekta albo analityka? Czy trzeba proponować akurat jedną z trzech niezbyt lubianych i niezbyt cenionych w środowisku ról? Często zdarza się, że wypalony zawodowo pracownik zwraca się z propozycją migracji poziomej, do innego zespołu czy na zupełnie inne stanowisko. Spotyka się z odmową. Jest bardzo potrzebny w obecnym miejscu pracy. A przecież taka możliwość migracji zawsze jest przed nim otwarta – nazywa się „rzucam papierami i idę do sąsiadów”. Czy zatem warto tracić człowieka bezpowrotnie? Czy może zamiast tego ułożyć naszą organizację tak, żeby wspierała potrzeby pracowników ?

Czy nie można zagadnienia tego rozwiązać w podobny sposób jak wspomniana na początku, święcąca sukcesy, strategiczna seria Cywilizacja? Przecież kompetencje techniczne także mają swoje prerekwizyty, które przy odrobinie dobrych chęci można rozrysować w formie zbliżonej do drzewa technologii. Żeby móc rozwijać aplikacje frontendowe w oparciu o AngularJS, wcześniej trzeba poznać język JavaScript. Żeby natomiast efektywnie używać JavaScript do implementacji aplikacji przeglądarkowych, przyda się zrozumienie zasad rządzących technologią web. Przykłady takich zależności można mnożyć w nieskończoność. Różne organizacje będą także miały inne podejście do niektórych zaawansowanych technologii, wynikające bezpośrednio z ich kontekstu i struktury.

Jak zatem wygląda wdrożenie takiego podejścia oraz na jakie bezpośrednie i pośrednie zyski możemy dzięki temu liczyć?

Wprowadzając dopasowane do firmy drzewo kompetencji, zyskujemy jednorodnie rozumianą przez wszystkich komunikację w zakresie umiejętności. “Frontend developer” w zależności od organizacji będzie reprezentował różny zestaw umiejętności. Czasem będą one skupione wokół programowania w JavaScript, innym razem natomiast z naciskiem położonym na tworzenie graficznego interfejsu użytkownika oraz efektywne użycie technologii HTML/CSS. Taka różnorodność powoduje powstawanie luk komunikacyjnych, które na szczęście można łatwo wyeliminować – głównie dzięki skupieniu na poszczególnych umiejętnościach, a nie na ich różnie nazywanych grupach.

Naniesienie na gotowe drzewa umiejętności konkretnych osób wyraźnie pokaże nam, jakie kompetencje posiadają nasi pracownicy. Zobaczymy też, jakie mogą szybko zdobyć, jeżeli pojawi się taka potrzeba. Będzie to także jasna wskazówka dla programistów (zwłaszcza tych młodszych), w jakim kierunku mogą się rozwijać i gdzie ich to zaprowadzi. Firma może ponadto zachęcać pracowników do zdobywania określonych kompetencji, które w najbliższej przyszłości będą potrzebne, na przykład z powodu rozpoczynającego się wkrótce projektu. Z kolei rozmieszczenie na gałęziach aktualnie rekrutowanych osób, pokaże nam, jak wyglądają one na tle zespołu i pozwoli kontrolować różnorodność kompetencyjną. Wszak zawsze warto mieć ludzi posiadających nie tylko wymagane umiejętności, ale także wiedzę wprowadzającą powiew świeżości.

Oczywiście, nic nie stoi na przeszkodzie, aby pozycję w firmie uzależnić od posiadanego zestawu umiejętności. Starszy programista to ktoś, kto dla przykładu zna na poziomie zaawansowanym przynajmniej trzy rzeczy. W ich zakresie może również pełnić rolę mentora dla mniej doświadczonych kolegów i koleżanek. Czy jednak znajomość jakiegoś tematu pozwala nam z marszu uczyć innych? A co z kompetencjami miękkimi? Czy jedno drzewo kompetencji wystarcza do opisu osoby? Okazuje się, że nie. Poza technologiami uczyć się musimy także komunikacji, współpracy w grupie, dzielenia się wiedzą itd. A to materiał na kolejne drzewo, po którym będziemy poruszali się równolegle. Zatem starszy programista, poza wskazaną powyżej wiedzą techniczną, musi wykazać się również znajomością zwinnych metod wytwarzania oprogramowania, umiejętnościami liderskimi oraz podstawami wystąpień publicznych (żeby na przykład poprowadzić demo przed klientem).

Każdy liść naszego drzewa – poza nazwą technologii – możemy opisać także listą książek, artykułów, prezentacji czy szkoleń, które pozwolą nam nabyć właściwe umiejętności. Dzięki temu w jednym miejscu gromadzimy informacje nie tylko o tym, czego możemy się nauczyć, ale także jak to zrobić.

Technologia żyje. Co chwilę pojawiają się nowe języki, biblioteki, narzędzia. Bieżące uwzględnianie tych wszystkich trendów, powoduje, że nasze drzewo kompetencji żyje. Jak każde inne drzewo rośnie i rozwija się. Pewne gałęzie się wzmacniają, inne pozostają w charakterze ozdobników lub są ucinane. Pamiętajmy o tym, a już nigdy zmiany technologii nas nie zaskoczą.

A co, jeżeli w Twojej firmie temat ścieżek kariery zupełnie nie jest uregulowany? Tym lepiej! Przy okazji wdrażania drzew kompetencji, możesz zrobić to od razu w optymalny i nowoczesny sposób! Pozwól pracownikom czerpać z pracy przyjemność, nie mniejszą niż z zabawy w Cywilizację.

Wyobraź sobie, że piszesz książkę. Zarywasz noce, zalewasz zmęczenie kolejnymi kubkami kawy, przemywasz przekrwione oczy zimną wodą… Po kilku miesiącach takiego maratonu – jest! Wysyłasz do najbliższych przyjaciół i z niecierpliwością czekasz na wyrok. Kilka rozmów później już wiesz, że lektura jest ciekawa, ambitna, nowatorska… ale? Ale byłaby znacznie lepsza, gdyby główny bohater był dojrzałą kobietą, a nie młodym chłopakiem. I co teraz? Przepisywać całą książkę? Ach, gdybyś tylko wiedział to wcześniej! Może po pierwszym rozdziale? Zaraz, zaraz, to czemu nie wysłałeś pierwszego rozdziału zaraz po jego ukończeniu?

Czemu nie uczymy się na cudzych błędach? Nie wyciągamy pomocnych wniosków, zanim doprowadzimy siebie i otoczenie do łez i frustracji? I jak możemy działać inaczej?

Spróbujmy przyjrzeć się popularnym podejściom do przyrostowego rozwoju produktu. Główną siłą napędową metodyk zwinnych jest szybka informacja zwrotna. Użytkownik otrzymuje „wydmuszkę” zaślepionej funkcji, która jednak pozwala mu choćby w minimalnym zakresie ją wykorzystać czy przetestować. Taką właśnie rolę pełni pierwszy napisany rozdział książki. Podobnie będzie wyglądało projektowanie środków komunikacji pokazane na poniższym rysunku.

Zakładając, że potrzebą użytkownika jest przemieszczenie się z miejsca na miejsce, możemy uznać, iż przyjęty harmonogram prac jest daleki od ideału. Pierwsze użycie produktu może nastąpić dopiero po ostatniej fazie projektu, czyli montażu kół. Analogicznie w projektach programistycznych jest to koncentracja na kwestiach technicznych. Zaczynamy od utworzenia modelu bazy danych, później implementujemy warstwę serwisową, a na samym końcu dostarczamy interfejs użytkownika. Dopiero teraz pozwalamy mu zapoznać się z budowanym (a w zasadzie już zbudowanym) systemem.

Jak inaczej zatem można planować pracę? Najczęściej spotykanym modelem iteracji jest ten przedstawiony poniżej.

Tutaj sytuacja pozornie wygląda znacznie lepiej. Już od samego początku użytkownik jest w stanie realizować swoją najważniejszą potrzebę, czyli przemieszczenie się z miejsca A do miejsca B. Czemu zatem pozornie? Problem w powyższym podejściu polega na porzucaniu wyników poprzednich iteracji. Oczywiście, w mocy pozostają retrospekcje i informacja zwrotna od użytkowników, jednak sam produkt jest realizowany poniekąd od zera. W przypadku projektów informatycznych problem taki wynika głównie z braku strategicznego planowania produktu, które broni się w zasadzie jedynie w przypadku niezwykle innowacyjnych projektów, przy których nie do końca jesteśmy w stanie przewidzieć zachowania, czy nawet potrzeb potencjalnych klientów.

Rozwiązanie idealne? Oczywiście wiemy, że takie nie istnieje. Natomiast w większości przypadków najlepiej sprawdza się sposób pokazany poniżej.

Klient otrzymuje podstawowy wariant realizacji wymagań już po pierwszej iteracji projektu. Co prawda, jechać można tylko do przodu i w dodatku „na pych”, ale worki z cementem możemy przetransportować na drugi koniec hali dość sprawnie. Po kolejnej iteracji możemy już kierować (okazało się to dość dużym brakiem pierwszej wersji) i siedzieć. Może nawet zakończymy projekt, bo klient nazwie to „buggy” i oceni, że całkowicie spełnia jego potrzeby? Jeżeli później przyjdzie jesień i okaże się, że karoseria i szyby chroniące przed deszczem jednak nie są przereklamowane, nic nie stoi na przeszkodzie, aby je „zaimplementować”.

Przenieśmy to teraz na grunt projektów software. Otrzymując jedynie interfejs użytkownika formularza rejestracji konta (zwracający zawsze informację, że wszystko zakończyło się sukcesem i nawet nie próbujący zapisywać nic do bazy danych), jesteśmy w stanie ocenić ergonomię rozwiązania. Jeżeli teraz okaże się, iż pól jest zbyt dużo i należy podzielić formularz na dwa rozdzielone kroki (np. jeden dostępny ze strony głównej, a drugi wyświetlany po pierwszym zalogowaniu do aplikacji), to dowiedzieliśmy się o tym, zanim wykonaliśmy jakąkolwiek implementację. Zmiana kodu, który jeszcze nie istnieje, nic nie kosztuje. Jeżeli jednak o tym samym dowiedzieliśmy się po dostarczeniu całej funkcji, podział formularza na dwa, zmiana walidacji i przepisanie API łączyłoby się z większym nakładem pracy i prawdopodobnie potraktowane zostanie jako zmiana wymagań. To właśnie takie modyfikacje opóźniają projekty i powodują dostarczanie rozwiązań dalekich od optymalnych.

Przytoczony na początku przykład z książką wyraźnie pokazuje, że im wcześniej uzyskamy informację zwrotną dotyczącą wykonanego produktu, tym bardziej efekt będzie dopasowany do potrzeb końcowego użytkownika. Co równie ważne, satysfakcja z wykonanej pracy będzie znacznie większa, a koszt jej wykonania zauważalnie niższy niż przy klasycznym podejściu, które przeprowadzenie ewaluacji zostawia na sam koniec. Oczywiście, nawet najbardziej zwinny system pisania książki nie pomoże, o ile recenzent odmówi czytania pojedynczych rozdziałów i postanowi czekać na ukończoną powieść. Ale warto próbować!

Pamiętajmy – miesiąc prac i planowania może zaoszczędzić nam godzinę poświęconą na uzyskanie opinii użytkownika 🙂

Ludzie dzielą się na na takich, którzy zabezpieczają swoje samochody na wszelkie możliwe sposoby, i na takich, którzy po prostu kupują autocasco. Okazuje się, że ten podział odnosi się także do informatyki.

Na chwilę oderwijmy się od ziemi i przenieśmy w przestrzeń kosmiczną. Na znajdujące się tam satelity działa bardzo wiele sił i zjawisk, a jednym z nich jest promieniowanie. Rozpędzone do prędkości kilkunastu tysięcy kilometrów na godzinę cząstki sieją spustoszenie w układach elektronicznych wszystkiego, co wysyłamy na orbitę. Jak wiemy, komputery nie używają pisma (nawet obrazkowego), a do przeprowadzania wszystkich operacji i przechowywania danych wykorzystują jedynie zera i jedynki. Dowolna informacja, jak na przykład liczba 23 (w systemie dziesiętnym), może być przedstawiona za pomocą odpowiedniej kombinacji zer i jedynek (w systemie dwójkowym) – w tym przypadku 10111. Jak widzimy, do zapisania ten informacji potrzebujemy pięciu komórek pamięci. Komórka pamięci, mimo że nie widać jej gołym okiem, jest obiektem fizycznym i ma swój rozmiar. Na tyle duży, że może w nią trafić zabłąkana cząsteczka alfa. Jeżeli tak się stanie, następuje tzw. bit-flip, czyli zamiana 0 na 1 bądź odwrotnie. Czyli 10111, po trafieniu cząsteczka zamienia się nagle na 10011 – czyli 19 w systemie dwójkowym. Jeżeli liczba ta mówi np. o wymaganym czasie działania silników, mamy poważny problem. Problem, który musimy rozwiązać. A możemy to zrobić na dwa sposoby. Sposób pierwszy to za wszelką cenę nie dopuścić do wystąpienia błędu, na przykład stosując zaawansowane (a przy okazji oczywiście drogie i ciężkie) osłony otaczające wrażliwe układy. To tzw. podejście fail-safe. Druga droga (safe-to-fail) polega z kolei na zaprojektowaniu takiego rozwiązania, w którym konsekwencje spowodowane błędem będą nieistotne. Skoro wiemy, że podczas wykonywania obliczeń nawigacyjnych może wkraść się błąd, najprostszym sposobem otrzymania prawidłowego wyniku jest… statystyka. Jeżeli dane działanie wykonamy kilka razy, możemy liczyć, że najczęściej otrzymywany wynik jest wartością prawidłową. Takie właśnie podejście z powodzeniem wykorzystuje firma SpaceX. Zamiast w jeden procesor ich systemy wyposażone są w trzy jednostki, z których każda posiada dwa rdzenie. W związku z tym każde działanie wykonywane jest sześciokrotnie, co pozwala skutecznie rozwiązać problem zabłąkanych cząstek. Czy da się jednoznacznie stwierdzić, która droga jest lepsza? Oczywiście nie, gdyż za każdym razem pod uwagę musimy wziąć kontekst zastosowania. Przeanalizujmy jednak mocne i słabe strony obu rozwiązań. Pierwsze pozornie wydaje się genialne w swojej prostocie – dodajemy osłonę i problem rozwiązany. Co jednak stanie się w momencie, kiedy osłona okaże się mniej skuteczna niż nam się wydawało, bądź jakiś kosmiczny śmieć po prostu ją uszkodzi? Szach-mat i zostajemy z niczym. Zrobiliśmy wszystko, aby nie dopuścić do wystąpienia błędu, jednak jeżeli już do niego dojdzie, konsekwencje są ogromne. W drugim przypadku dopuszczamy natomiast możliwość wystąpienia błędu, ale jednocześnie ograniczamy do minimum jego konsekwencje. Co za tym idzie, nawet jeżeli zawiedzie jeden procesor, w dalszym ciągu zostaje nam pięć, które dalej skutecznie będzie prowadziło naszego satelitę.

Teraz wróćmy więc do ziemskiego biznesu i poszukajmy podobnych sytuacji. Jedną z nich będzie choćby zapewnienie prawidłowego funkcjonowania naszego oprogramowania. Stosując podejście fail-safe, zbudujemy naszą procedurę wdrożeniową tak, aby wersja wchodząca na środowisko produkcyjne, była wolna od jakichkolwiek błędów. Z reguły przekłada się to na dość rozbudowaną fazę testów, które niezależnie od tego, czy są manualne, czy automatyczne, kosztują sporo i trwają dłużej niż byśmy sobie tego życzyli. Ponadto, często już podczas testów wdrażane są kolejne wersje, poprawiające wykryte błędy, jednak – czego nie można wykluczyć – wprowadzające także kolejne, np. w funkcjach, których scenariusze już zostały „odhaczone na zielono”. Ponadto, przyjęte podejście powoduje, że bardzo niechętnie podejmujemy poważne decyzje projektowe, takie jak odmergowanie problematycznego projektu czy wprowadzenie innej większej zamiany, gdyż powodują one potrzebę powtórzenia wszystkich zakończonych już procedur. Taki właśnie problem doprowadził do katastrofy promu Challenger. Kierownictwo projektu nie uwierzyło inżynierowi, który opisał problem mogący doprowadzić do katastrofy, gdyż byli przekonani, że tak poważna wada zostałaby wykryta na wcześniejszych etapach, a sama konieczność jej sprawdzenia spowodowałaby przesunięcie już i tak opóźnionego startu.

Jak wygląda zatem implementacja podejścia safe to fail w rozpatrywanym przypadku? Przede wszystkim musimy wyróżnić dwie grupy funkcji naszego systemu: krytyczne i pozostałe. Dla tych krytycznych tworzymy standardową ścieżkę testową i weryfikujemy je end-to-end przy każdym wdrożeniu. Praktyka pokazuje jednak, że stanowią one z reguły nie więcej niż 20% całości. Jest to już dużo bardziej realny i efektywny cel automatyzacji testów. Nie zmienia to faktu, że pozostało nam jeszcze niezaadresowane 80% systemu. Czy aby na pewno? Już w 1999 r. Kent Beck zaproponował koncepcję „test-first” stanowiącą jeden z filarów programowania ekstremalnego. Kilka lat później wyodrębniono to jako niezależną technikę zwaną „test-driven development”, której umiejętne stosowanie zapewnia od samego początku odpowiednie pokrycie testami jednostkowymi tworzonego oprogramowania, co z kolei zapewnia, że system działa zgodnie z intencją programisty. Nie oznacza to niestety jednak poprawnego funkcjonowania w rozumieniu odbiorcy końcowego. Jak już jednak wiemy, dążymy przede wszystkim do ograniczenia negatywnych konsekwencji błędów. Pierwszy krok polegający na zabezpieczeniu krytycznych funkcji już wykonaliśmy. Kolejnym będzie zatem ograniczenie „czasu życia” pozostałych błędów w środowisku produkcyjnym. Nawet drobny błąd, jeżeli występuje przez wiele dni czy tygodni, może doprowadzać użytkowników do pasji i skutkować negatywną opinią o naszym systemie. Jednak ten sam błąd usunięty w ciągu przykładowo 30 minut zostanie przez odbiorcę bardzo szybko zapomniany. Co jednak możemy zrobić, aby być w stanie przygotować i wdrożyć poprawkę w takim czasie? Przede wszystkim nie zawsze aż tak wyśrubowana reakcja będzie konieczna. Jeżeli jednak tak się stanie, należy rozbić ten czas na kilka składowych i w zależności od możliwości ukierunkować odpowiednio wysiłki:

  • czas wykrycia błędu – tym krótszy, im bardziej ułatwimy klientowi wysłanie zgłoszenia lub im szybciej zareaguje nasz monitoring,
  • czas diagnozy – tym krótszy, im mniejsza jest paczka zmian od ostatniego wdrożenia – czyli im częściej wykonujemy wdrożenia, tym mniejsze paczki zmian one zawierają i tym łatwiej znaleźć zmianę, która wprowadziła błąd,
  • czas poprawy – im lepsza jakość kodu i testów jednostkowych, tym szybciej możemy błąd odtworzyć i poprawić,
  • czas wdrożenia – im wyższy stopień automatyzacji, tym krócej trwa pipeline (procedura) wdrożenia naszej aplikacji.

Podsumowując: zrozumienie przedstawionych powyżej podejść wraz z ich konsekwencjami i odpowiednim zarządzaniem ryzykiem, pozwala nam w skuteczny i efektywny w kontekście czasu i zasobów sposób dostarczać odpowiednio wysokiej jakości oprogramowanie. O ile jednak stosowanie safe to fail wydaje się lepszym pomysłem, należy szczerze odpowiedzieć sobie, czy obecna jakość wdrażanego systemu pozwala je prosto wdrożyć. Co ciekawe, nawet negatywna odpowiedź na postawione powyżej pytanie nie wyklucza możliwości jego stosowania. Za pomocą odpowiednich technik, jak choćby wdrożeń kanarkowych czy też procedur rollback, możemy zawsze „upiększyć” rzeczywistość. Jednak jest to już temat na inny artykuł.

Czy będzie to blog o programowaniu? Nie, chociaż jest skierowany do programistów. Czy będzie to w takim razie blog o biznesie? Nie, chociaż jest skierowany również do przedsiębiorców i biznesu. O czym w takim razie zamierzam pisać?

Od blisko 30 lat pasjonuję się programowaniem. Zaczynałem już jako kilkuletnie dziecko, pisząc w Fortranie 77 proste programy pomagające mi w lekcjach – jak choćby w liczeniu „słupków” na matematykę. Pasją rozwiązywania problemów za pomocą programowania zaraził mnie Tata. Z zawodu aerodynamik, szeroko wykorzystuje metody numeryczne i oczywiście programowanie do optymalizacji procesu projektowania samolotów. Ponad 14 lat temu moja pasja przerodziła się w zawód, z którym jestem związany do dziś. Początkowo jako programista, później projektant i architekt, team leader i manager aż do trenera, konsultanta i przedsiębiorcy rozwijającego własną firmę. Zwłaszcza to ostatnie zajęcie wpłynęło na ewolucję mojego podejścia do wytwarzania oprogramowania. Bycie równolegle po obu stronach pozwala spojrzeć na styk IT i biznesu z szerszej perspektywy. Pozwala zrozumieć (co nie spodoba się wielu zatwardziałym programistom), że IT nie powinno być celem samym w sobie, a jedynie (i jednocześnie aż) środkiem do realizacji wartości biznesowej. Oczywiście, środek ten należy właściwie rozumieć i wykorzystywać, jednak nie należy  przy tym zapominać, że nadrzędnym celem oprogramowania, jest zaspokojenie potrzeb odbiorcy – a nie twórcy.  Muszę jednak także podkreślić (co z kolei nie spodoba się zatwardziałym przedstawicielom biznesu), że dbanie o jakość i formę dostarczanego oprogramowania także jest niezbędne, jeżeli chcemy z niego z powodzeniem korzystać dłużej niż kilka miesięcy.

I właśnie o tym styku tych dwóch nurtów będzie ten blog. Postaram się przedstawić różne podejścia, pomysły czy rozwiązania, które pozwolą (mam nadzieję) upiec dwie pieczenie przy jednym ogniu:

  • zbudować nić porozumienia i budować wzajemne zrozumienie ostatecznie usuwające barykady i zasieki zbudowane między produktem, rozwojem i utrzymaniem,
  • szerzyć pragmatyczną, opartą na inżynierii i twardych liczbach strategię prowadzenia działu IT.

Bardzo liczę także na szczerą informację zwrotną, konstruktywną krytykę oraz otwartą dyskusję pod poszczególnymi postami czy też za pośrednictwem e-maila.

Pozdrawiam i zapraszam do lektury,
Jakub Kubrynski