Kontynuuję temat Developerstwa Zwinnego, z którym mieliście okazję zapoznać się w poprzednim moim tekście. Opowiedziałem w nim o tym, że praca w zespołach samozarządzających się jest jedną z cech, która wyróżnia takiego Developera od zwykłego „Code Monkey”. Dziś opowiem o innej cesze: rozumieniu wartości oprogramowania.
Poprzedni wpis z cyklu „Od Code Monkey do Developera zwinnego” dotyczył Wartości Scrum,
Na początek opowiem historię z własnego doświadczenia. Chodzi o to, jak tworzyłem aplikacje, kiedy uczyłem się programowania. Miałem wtedy około 16 lat, więc trochę czasu minęło. Pisałem aplikacje typowo do 500 linii kodu w C++, najczęściej gry terminalowe. Pisałem je w pojedynkę. Jeśli chciałem poeksperymentować z działającym kodem – robiłem kopię do innego katalogu. Nie wiedziałem wtedy, jak mocno procesy zawodowych programistów różnią się od mojego. Nie wiedziałem nic o repozytoriach kodu, Clean Code lub o formatowaniu typu CamelCase, ale też instynktownie rozumiałem, że zmienne i funkcje powinny mieć jakieś sensowne nazwy. Dla porównania, mój kolega wszystkie zmienne w swoich aplikacjach nazywał „bob”, bo to go bawiło. Jego kod wyglądał mniej więcej tak:
if(bob1 != bob2) return bob3;
Jak widać, mieliśmy różne style pisania kodu, ale każdy z nas pisał ten kod tylko dla siebie i nie przejmował się tym, jak dobrze czy źle będzie on zrozumiały dla kogoś innego. W zawodowym tworzeniu oprogramowania kod pisze się nie dla zabawy, a dla różnych przedsiębiorstw, żeby pomóc im w prowadzeniu swej działalności. Zazwyczaj to wymaga dużych i złożonych aplikacji, których jeden człowiek nie potrafi wytworzyć. Potrzebny jest zespół, a czasami wiele zespołów, które wspólnie będą tworzyć te aplikacje i systemy.
Tu powstaje problem, ponieważ im więcej ludzi pracuje nad aplikacją, tym bardziej wzrasta jej złożoność, a więc, tym więcej powstaje okazji do błędów, bugów i porażek.
Jednocześnie zmniejsza to szansę na to, że klient dostanie: a) to, czego potrzebuje, b) w miarę szybko i c) dobrej jakości.
Na szczęście, proces tworzenia oprogramowania ewoluował i wciąż ewoluuje. Pojawiły się gotowe rozwiązania typowych problemów, bez których większość dzisiejszych programistów nie wyobraża sobie życia, na przykład:
- Biblioteki oraz frameworki – żeby nie robić wszystko od zera, a korzystać ze sprawdzonych rozwiązań.
- Testy (jednostkowe, integracyjne, itp.) – żeby mieć więcej kontroli nad sprawdzaniem, czy kod działa tak, jak tego oczekujemy.
- Systemy wersjonowania kodu i pipeline CI/CD, które zapewniają, że żadne zmiany nie zepsują roboczej wersji aplikacji.
- Wzorce projektowe i Clean Code, dzięki którym nie musimy się zastanawiać, za co odpowiada zmienna o nazwie bob17.
Te wszystkie rozwiązania pozwoliły istotnie obniżyć złożoność i nieprzewidywalność procesu tworzenia oprogramowania. Dały też zabezpieczenie przed wieloma błędami krytycznymi. Robi mi się słabo, gdy myślę o czasach, kiedy programiści pracowali bez tych wszystkich narzędzi. Wtedy to wyglądało podobnie, jak moje zabawy w oprogramowanie gdy miałem 16 lat – tylko zaangażowano w to wielu ludzi jednocześnie, a klient wymagał od nich konkretnych rezultatów. W końcu za to płacił, a więc trzeba było debugować do nocy, żeby zrozumieć, dlaczego bob25 zwraca null.
Wyżej wymienione techniki i technologie są dziś niezbędne w tworzeniu oprogramowania wysokiej jakości. Nawet więcej, trudno bez nich w ogóle wytworzyć działającą aplikację. Nie wystarczy jednak, że ona zadziała. Kod sam w sobie nie ma żadnej wartości. Klient zawsze płaci za narzędzie, które będzie rozwiązywało jego problemy biznesowe, a co znajduje się pod maską mało go obchodzi. Kod, a nawet gotowe aplikacje nie są celem, tylko środkiem do osiągniecia celu.
Klient, swoją drogą, chce osiągać swoje cele, a nie słuchać o tym, jak dobre mamy środki. Nie bez powodu Agile Manifesto twierdzi: „Ludzie oraz interakcje znaczy więcej, niż procesy i narzędzia.”
Czyli, wartość oprogramowania polega na tym, jak ono pomoże klientowi zwiększyć przychody od swej działalności lub zmniejszyć wydatki. W gruncie rzeczy i jedno, i drugie jest sposobem na zwiększenie zysku, który generuje biznes klienta. A więc, aplikacja jest inwestycją: klient wydaje pieniądze na jej wytworzenie (wynagrodzenie Developerów, sprzęt, serwery, etc.) z myślą, że z czasem odzyska dzięki niej o wiele więcej pieniędzy. Bo jeśli nie, to znaczy, że inwestycja była zła: była marnowaniem środków i czasu. A więc i tworzenie oprogramowania bez wartości biznesowej jest marnowaniem środków.
Wartość biznesowa = zysk z aplikacji/wartość jej wytwarzania
Czyli, powinniśmy tworzyć oprogramowanie, które nie tylko działa, a też zaspokaja potrzeby klienta. I tu znowu złożoność oraz nieprzewidywalność zaczynają wzrastać. Już pisałem o tym, że Developerzy i Interesariusze mówią w różnych językach i często trudno im zrozumieć siebie nawzajem. Problemy, które mają rozwiązywać aplikacje, są (znowu) złożone i trudne do zrozumienia komuś kto nie ma wiedzy domenowej (Developerom). Tak samo jak narzędzia typu CI/CD obniżają złożoność oraz nieprzewidywalność, która się wywodzi z samej natury kodu.
Zwinne metodyki obniżają złożoność oraz nieprzewidywalność, która wywodzi się z biznesu:
- Agile uczy nas, że Developerzy muszą współpracować z biznesem codziennie. Muszą też często dostarczać nowe przyrosty, żeby uzyskiwać opinie klienta i jak najszybciej móc naprawić to, co nie pasuje. W ten sposób pokonujemy „barierę językową” pomiędzy Developerami, a Interesariuszami.
- W Scrumie zawsze mamy Cel Produktu, który pomaga Developerom zrozumieć, czego rzeczywiście życzy sobie klient. Dzieląc ten Cel na konkretne kroki, uzyskujemy Cele Sprintu. Dzięki nim, w każdej chwili cały zespół Developerów jest skupiony na dążeniu do tego celu. Przy okazji dzięki temu unikniemy sytuacji, gdzie poświęcamy się tworzeniu czegoś, co dla klienta nie ma wartości.
- Scrum też jednoznacznie twierdzi, że nie ma „technicznych” czy „specjalnych” Sprintów. W każdym Sprincie musimy wytworzyć coś, co ma wartość biznesową, bez wyjątku. Gdyby zespół spędził miesiąc na „refaktoryzacji kodu” lub czymś w tym stylu, to ze strony klienta by wyglądało, że robią nie wiadomo co. Dlatego na końcu zawsze musi pojawić się wartość biznesowa. A jeśli czujemy potrzebę „technicznego Sprintu”, to znaczy, że powinniśmy zastanowić się na kolejnej Retrospektywie, dlaczego tak jest
- Agile uczy nas, że powinniśmy być gotowi na porażkę i traktować ją jako źródło nowej wiedzy. W Scrumie mamy regularne Retrospektywy, gdzie badamy to, jak pracujemy. Jeśli widzimy, że mamy potrzebę „technicznego Sprintu”, najczęściej to znaczy, że trzeba ulepszyć Definition of Done. Bo co z tego, że mamy techniki (testy, pipeline’y, itp.), jeśli nie potrafimy wykorzystać ich do tworzenia wartości biznesowej?
Współczesne aplikacje są zbyt złożone, żeby jeden człowiek mógł je wytworzyć w całości. Im więcej ludzi pracuje nad aplikacją, tym bardziej wzrasta złożoność kodu i tym trudniej (drożej, dłużej) dowieźć aplikację działającą i o dobrej jakości. Różne technologie i frameworki (jUnit, GitLab, Jenkins, etc.) czynią proces pisania kodu prostszym. Jakość kodu jest konieczna, ale niewystarczająca – oprogramowanie musi też mieć wartość biznesową.
Wartościowa aplikacja zawiera tylko te funkcje, które rozwiązują biznesowe problemy klienta. Zwinne metodyki powstały, żeby wesprzeć proces tworzenia takich aplikacji. Spośród organizacji, które tworzą oprogramowanie, wygrywają te, które zapełniają maksymalną wartość biznesową, czyli zdolność do rozwiązywania problemów swego klienta.