Centrum sterowania wszechświatem

Wytwarzanie oprogramowania jest nieustannym zmaganiem się ze złożonością: zmienia się technologia, potykamy się o dług techniczny pozostawiony we wcześniej wytworzonym kodzie, ludzie mają gorszy lub lepszy dzień, różne umiejętności, zdarza im się niespodziewanie odejść z pracy. O ile z tym można sobie jeszcze jakoś radzić, o tyle nie sposób uniknąć ani przewidzieć ciągłej ewolucji potrzeb, a co za tym idzie zmiany wymagań opisujących funkcjonalności i cechy oprogramowania. Właściwie jedyną rzeczą pewną przy tworzeniu oprogramowania jest to, że wymagania te będą się nieustannie zmieniać.

„Konfigurowalność” na ratunek

Biznes ma świadomość tej zmienności potrzeb i oczekuje, że oprogramowanie, jakie otrzymuje, będzie sobie z nią radzić. Sytuacja, w której modyfikacja sposobu działania tej czy innej funkcjonalności wymaga wprowadzenia dużych zmian w kodzie, a co za tym idzie dużo czasu, jest niepożądana. W tradycyjnych metodach prowadzenia projektów konieczność uwzględnienia takich zmian powodowała spory problem i – najczęściej – opóźnienia w realizacji wcześniej poczynionych planów. Metody zwinne (na przykład Scrum) pozwalają dokonywać takich zmian co iterację, ułatwiając dopasowywanie produktu do potrzeb biznesu.

Konieczności radzenia sobie ze zmiennością wymagań od lat towarzyszy pokusa, by tworzyć „konfigurowalne rozwiązania”. Koncepcja jest prosta: zamiast ciągle zmieniać kod, możemy regulować jego działanie poprzez różne parametry, które tym działaniem sterują. Wymaga to być może bardziej rozbudowanych rozwiązań, ale jak już zostaną one wytworzone, dalszy development wydaje się niepotrzebny lub będzie ograniczony. Są miejsca, gdzie biznes wprost domaga się wbudowania takich mechanizmów adaptacyjnych w oprogramowanie, gdzie indziej zespoły developerskie z własnej inicjatywy tworzą „konfigurowalne rozwiązania” aby poradzić sobie z koniecznością dokonywania szybkich zmian.

Nie twierdzę, że takie podejście nigdy nie ma sensu – o ile takich parametrów konfiguracyjnych jest kilka, może kilkanaście, i o ile da się realnie sprawdzić zachowanie oprogramowania przy różnych sposobach jego skonfigurowania, to może być dobry pomysł. Realnie oznacza to stosunkowo małą aplikację lub prosty system, w którym jakieś funkcjonalności lub cechy można modyfikować, bez naruszenia lub zmienienia podstawowych zasad działania. Co zaskakujące, prawie nigdy twórcy takich rozwiązań nie wpadają jednak na pomysł uczynienia ich „konfigurowalnymi”, bo dochodzą do wniosku, że szybciej dokonywać po prostu zmian w kodzie…

W jaki sposób zbudować centrum sterowania wszechświatem

Niestety, koncepcja „konfigurowalności” jest kluczem do tworzenia rozwiązań w miejscach, gdzie nie ma ona za grosz sensu. Przede wszystkim w firmach tworzących dla siebie lub dla klientów duże i złożone systemy informatyczne. Poprzez dodanie do nich całej masy (nierzadko setek, czasem tysięcy) parametrów sterujących działaniem oprogramowania, złożoność rośnie wykładniczo. Wytworzenie takich rozwiązań staje się ekstremalnie drogie i czasochłonne, ponieważ każdy dodany przełącznik lub parametr wymaga sprawdzenia na okoliczność interakcji z tymi już istniejącymi.

Jeśli dodać do tego różnorakie wariacje danych, jakie systemy informatyczne muszą przetwarzać, konieczność radzenia sobie z niespójnościami tych danych, rozłożone w czasie procesy ich przetwarzania… W żadnym akceptowalnym czasie nie da się takich rozwiązań ani zbudować, ani tym bardziej zweryfikować poprawności ich działania. Zaczyna się wtedy powolne ograniczenie zakresu testów do „tego, co najważniejsze” – czego skutkiem jest powolna kumulacja długu technicznego. Ba, dochodzi się do etapu, w którym nie do końca już wiadomo, które przełączniki są używane, a które nigdy nie zmieniają wartości. Widziałem też takie systemy, gdzie już nie pamiętano, co dokładnie konfigurował ten czy ów parametr.

Duże firmy mają tendencję do budowania centrów sterowania wszechświatem: systemów (pozornie) odpornych na zmienność potrzeb biznesowych, bo (pozornie) gotowych na dokonanie zmian działania w sposób (pozornie) bezpieczny i szybki.

Warto podkreślić, że metody zwinne nie wyrugowały tego problemu, a czasami mam wrażenie, że go wręcz nasiliły. Duże firmy transformując się do Agile bardzo często oczekują, że dzięki temu wszystko będzie „bigger, better, faster, cheaper” (to powiedzonko jednej ze znanych mi osób), czyli krótko mówiąc biznes dostanie rozwiązania taniej i szybciej. „Konfigurowalność” dla wielu zespołów jest jedyną odpowiedzią na wywieraną na nich presję, by dostarczały rozwiązania szybciej i w większej ilości. Jakość spada na drugi plan.

Agile oznacza zdolność do adaptacji

Czy owa „konfigurowalność” rzeczywiście umożliwia zwinne działanie? Mam wątpliwości. Dużym wysiłkiem wbudowujemy w rozwiązanie mechanizmy, które są nam zbędne dziś, ale „na pewno” przydadzą się w przyszłości (skąd niby możemy to wiedzieć?). Te wszystkie parametry są niczym oblepianie plastrami kikuta po urwanej nodze w nadziei, że ona jakimś cudem odrośnie. Dlaczego? Ponieważ zamiast ułatwiać nam dokonywanie zmian w oprogramowaniu powiększają jego złożoność, a nierzadko i wagę liczoną w tysiącach linii kodu, efektywnie utrudniając przyszłe modyfikacje.

Ktoś zakrzyknie: zaraz, chwila, moment, przecież właśnie o to chodzi, by nie musieć kodu zmieniać!

Warto zadać sobie pytanie, czy osiągnięcie takiego stanu jest w ogóle możliwe. Odpowiedź, w sumie oczywista, jest taka: nie. Aby mieć parametry gotowe do zmiany każdego możliwego aspektu działania oprogramowania, musielibyśmy ich mieć tysiące (lub miliony dla dużych systemów). Co więcej, aby określić co i w jakim zakresie ma się dać „konfigurować”, konieczne byłoby pełne przeanalizowanie nie tylko bieżących potrzeb (jak w starym, włochatym Waterfallu), ale też wszystkich przyszłych potrzeb (sic!). Jeśli tego nie zrobimy, ta nasza „pełna konfigurowalność” jest niekompletna i nieuniknionym stanie się zmienianie kodu, które będzie… piekielnie trudnie i powolne ze względu na złożoność rozwiązania.

Często na szkoleniach mówię, że prawdziwa zwinność wymaga budowania takich rozwiązań, które da się łatwo modyfikować. Zamiast przygotowywać się na nieuniknione przyszłe zmiany i próbować przewidywać ich charakter, twórzmy oprogramowanie tak „lekkie” i proste w modyfikacjach, jak to możliwe. Pozbywajmy się wszystkiego, co nie jest niezbędne, upraszczajmy sposób funkcjonowania. Im mniej kodu i funkcjonalności, tym łatwiej dokonywać zmian i w pełni przetestować wpływ tego, co się zmieniło, na pozostałą funkcjonalność. Dużo też łatwiej określić w jaki sposób rozwiązanie działa dziś, nie wymaga to konieczności analizowania ogromnego zestawu parametrów konfiguracyjnych…

Co na to biznes?

W szaleństwie „konfigurowalności” bardzo często wychodzi brak profesjonalnego podejścia ze strony developerów, którzy zamiast uświadomić biznesowi konsekwencje przesadnej parametryzacji godzą się na budowę wspomnianego wcześniej centrum sterowania wszechświatem.

Natomiast sam biznes też nie jest bez winy. Bez żadnej dającej się ekonomicznie uzasadnić potrzeby nadmiernie komplikuje funkcjonalności, zamiast dążyć do ich maksymalnego uproszczenia. Wynika to albo z niewiedzy, jakie są realne koszty wytworzenia i utrzymania w działaniu oprogramowania, które na to pozwoli, albo – co może zapowiadać ekonomiczną katastrofę – z niezrozumienia, co warto w produkcie mieć, a czego można się pozbyć.

Osoby pracujące w rolach Agile Coacha, Scrum Mastera czy Product Ownera są niejako z definicji odpowiedzialne za edukowanie biznesu w tym obszarze. Koniecznym jest wyjaśnienie, że zdolność do szybkiej adaptacji do potrzeb rynkowych oznacza konieczność racjonalizacji ilości rozwiązań i stopnia ich złożoności tak, by móc dokonywać szybkich zmian. „Konfigurowalność” nie jest rzeczywistym mechanizmem adaptacyjnym, ponieważ nie eliminuje konieczności dokonywania dalszych zmian, tylko je utrudnia, generując niepotrzebne koszty.