Celowe produkty poboczne

Dlaczego powstaje nadmiernie skomplikowane oprogramowanie i jak temu zapobiec?

Podstawowe prawa statystyki sugerują, że większość programistów dostarcza przeciętne produkty, wspierające zwykłe procesy biznesowe, pomagając zwyczajnym firmom działać bez zbytnich emocji. Chociaż właściwą decyzją dla takich produktów powinien być „wybór nudnej technologii” (jak to ładnie opisał Dan McKinley), bardzo niewiele zespołów faktycznie tak postępuje. Prowadzi to do powstania skomplikowanego oprogramowania, które jest kosztowne rozwijaniu, testowaniu i utrzymaniu. W dłuższej perspektywie złe wybory technologiczne powodują generowanie długu technologicznego, wymagają kosztownej migracji i spowalniają wdrożenia. W efekcie nadmiernie skomplikowane produkty utrudniają użytkownikom zadania, w których w założeniu miały pomóc. Przyczyny, dla których te decyzje są podejmowane są czysto ludzkie, a nie techniczne. W tym poście omówię kilka typowych powodów, dla których tak się dzieje, i pokażę, jak celowe inwestowanie w produkty poboczne jest dobrym sposobem na zapobieganie nadużywaniu technologii, powodując, że wszyscy są zadowoleni.

Sukces, czy porażka?

Zanim przejdziemy dalej, muszę coś wyznać. Na początku lat dziewięćdziesiątych miałem zlecenie na budowę systemu zarządzania treścią dla wydawcy. Było to przed pojawieniem się przyzwoitych webowych systemów CMS bazujących na otwartym kodzie źródłowym, więc firmy nadal budowały własne. Pieniądze nie były szczególnie atrakcyjne, a zadanie nie było ekscytujące. Klient potrzebował interfejs CRUD do prostej bazy danych. Mimo to zlecenie wydawało mi się pracą marzeń, ponieważ miałem okazję pobawić się Enterprise Java Beans. Powstała bardzo przekombinowana architektura, z ziarnami sesji i encji magicznie replikowanymi pomiędzy parą aktywnych serwerów ze zdalnymi interfejsami i mechanizmem replikacji, chociaż system mógł skutecznie działać na jednej maszynie i nigdy nie potrzebował natychmiastowego przełączania awaryjnego lub jakichkolwiek zabezpieczeń innych niż codzienne kopie zapasowe bazy danych. Trudno powiedzieć, czy produkt okazał się sukcesem biznesowym, ale klient był zadowolony, bo dostarczyliśmy „na czas i w budżecie”. Fakt, że zarówno czas, jak i budżet były mocno zawyżone ze względu na nasze techniczne decyzje, tak naprawdę nie miał znaczenia, a co bardziej prawdopodobne, przedstawiciele klienta nawet nie byli tego świadomi. W końcu byliśmy ekspertami technicznymi. Z czysto technicznej strony uważam to za ogromną porażkę, ponieważ znacznie szybciej byłoby po prostu stworzyć kilka skryptów CGI w Perlu, które robiłyby to samo. Jednak klient był typu “Enterprise”, więc prosta aplikacja w Perlu wydawała się zbyt trywialna, a oni mieli chęć i pieniądze, aby zapłacić za “Enterprise Beans”. Od strony osobistej, chociaż teraz wstydzę się technicznego aspektu tej historii, był to jeden z najcenniejszych projektów, w jakie kiedykolwiek byłem zaangażowany. Dowiedziałem się wiele o EJB w czasach, gdy była to nowa technologia, więc mogłem wynegocjować lepsze stawki dla wielu moich kolejnych zleceń. Minęło dobrych kilka lat, zanim branża zdała sobie sprawę, jak bardzo skomplikowane są Enterprise Java Beans i zanim framework Spring zdobył znaczący udział w rynku. Kiedy opowiadam tę historię na konferencjach, większość ludzi na widowni mówi o podobnych doświadczeniach. Hasła i technologie są różne, ale rezultat taki sam.

Nudne produkty

Dla tych z nas w IT, którzy chcieli tworzyć rzeczy, a nie zajmować się informatyką jako dziedziną akademicką, jednym z kluczowych czynników motywacyjnych jest możliwość wyrażania kreatywności w użyteczny sposób. Ale przeciętny problem biznesowy jest z definicji zwyczajny i nieciekawy. W konsekwencji większość ludzi nie może odnaleźć kreatywności i przyjemności w biznesowej stronie swoich produktów, więc muszą szukać tego w aspektach technicznych. W końcu nie brakuje nowych bibliotek, widżetów i gadżetów do wypróbowania. Trudno być zafascynowanym budowaniem kolejnej brzydkiej strony internetowej, która komunikuje się z kolejną głupią bazą danych do przechowywania zamówień i generowania faktur. Ale zrobienie tego za pośrednictwem mikroserwisów, które komunikują się z jeziorem danych (data lake) za pośrednictwem magistrali zdarzeń (event bus), sprawia, że ​​całe ćwiczenie jest nie tylko nieco bardziej znośne, ale wręcz ekscytujące. To jak Minecraft dla dorosłych i jeszcze dostajesz za to przyzwoitą pensję. Ale wprowadzanie niepotrzebnej złożoności do oprogramowania nie jest tym, za co powinniśmy być wynagradzani.

Relacja firma-pracownik

Kolejną siłą, którą należy wziąć pod uwagę, jest milcząca prawda o relacji pracodawca-pracownik na rynku oprogramowania. Bardzo rzadko można znaleźć szczerą lojalność u którejkolwiek ze stron. Duże korporacje w większości spędziły ostatnie dwie dekady na outsourcingu, zwalnianiu i masowym przesuwaniu ludzi. Mniejsze firmy mogą potrzebować szybko zatrudnić i wdrożyć pracowników wraz ze zwiększającym się popytem, ale nie mają one zbyt wysokiego wskaźnika przetrwania na rynku. Firmy średniej wielkości często wolą podwykonawców od pracowników z uwagi na przepisy podatkowe i możliwość obejścia prawa pracy. Wszyscy potrzebują elastyczności przy zatrudnianiu (i zwalnianiu) ludzi. Wraz ze starzeniem się technologii coraz trudniej jest znaleźć ludzi, którzy chcą nad nią pracować. Dużo prościej jest znaleźć ludzi, którzy chcą pracować z najnowszą wersją Reacta lub Angulara, niż tych, którzy chcą utrzymywać starą witrynę ASP lub, nie daj Boże, zbudować nową. Posiadanie nowej, kuszącej technologii w ofercie pracy ułatwia przyciągnięcie pracowników. Nie zapominaj, że ludzie, którzy znają stare technologie, są zwykle starsi, mają wyższe wydatki na życie i wyższe oczekiwania płacowe. Nowsza technologia pozwala firmom zatrudniać młodszych pracowników i płacić im mniej.

Z drugiej strony, dzisiejsi pracownicy mają tendencję do zmiany pracy znacznie częściej niż ich rodzice, szukając lepszych zarobków a nawet uciekając przed nudą. Ogromna część osób w branży nie jest tak naprawdę zatrudniona, ale pracuje jako krótkoterminowi podwykonawcy i konsultanci. W dzisiejszych czasach bezpieczeństwo pracy polega nie tyle na utrzymaniu stanowiska, ile na możliwości łatwego znalezienia nowego zatrudnienia. Praktyczne doświadczenie w atrakcyjnych, nowych technologiach ułatwia szybkie znalezienie nowej pracy, jeśli zajdzie taka potrzeba.

Goniąc króliczka

Nawet jeśli jest to nieświadoma decyzja, wielu programistów skorzysta z możliwości użycia nowej, kuszącej technologii, a większość firm na to pozwoli. Powodem, dla którego takie zachowanie jest nie tylko tolerowane, ale często promowane, jest to, że jest ono również dobre dla pracodawców. Gonienie zaawansowanego technologicznie “króliczka” sprawia, że ludzie przez pewien czas cieszą się swoją pracą i nie należy tego lekceważyć. Zapewnienie ludziom ekscytującej pracy pomaga w utrzymaniu pracowników, co zmniejsza koszty związane z zatrudnieniem i pozwala uniknąć utraty wiedzy z organizacji. Nawet jeśli produkt nie wymaga najnowszych technologii, danie ludziom szansy na zabawę z nimi w ich obecnej pracy oznacza, że nie muszą zmieniać firm, aby być na bieżąco z nowymi trendami rynkowymi.

Zabawa nowymi technologiami to także stosunkowo tani sposób na edukację pracowników w miejscu pracy. Świat oprogramowania zmienia się co kilka lat w dramatyczny sposób. Dwadzieścia lat temu Internet eksplodował. Dziesięć lat temu były to urządzenia mobilne. Teraz jest to trend na usługi w chmurze. Zbyt długie pozostawanie przy starej technologii sprawia, że produkty są przestarzałe i trudne do sprzedania. Kiedy nadchodzi kryzys, posiadanie wewnętrznej wiedzy na temat nowych technologii może być niezwykle przydatne. Zamiast płacić za drogie programy szkoleniowe dla pracowników, możesz po prostu zostawić programistów samym sobie z odrobiną kawy, a oni dokształcą się i poprawią swoje umiejętności. Wprowadzenie nowej, atrakcyjnej technologii do produktu, zanim będzie ona potrzebna, może zaszkodzić produktowi, ale zmniejszy koszty przekwalifikowania pracowników lub zatrudnienia zewnętrznych konsultantów, którzy w przyszłości wniosą wiedzę specjalistyczną.

Celowe produkty poboczne

Balansowanie wśród wszystkich tych sił jest nie lada wyzwaniem dla wielu firm programistycznych. Bez jasnej strategii nowa, atrakcyjna i zbędna technologia zwykle znajdzie drogę do Twoich produktów w sposób, którego nie chcesz. Dlatego sugeruję celowe posiadanie produktów pobocznych, w których programiści mogą eksperymentować, nie ryzykując głównego nurtu pracy.

Celowe produkty poboczne powinny od początku zakładać, że będą miały jedynie drugorzędną wartość biznesową i mogą nigdy nie zostać prawidłowo wydane. Nie należy oczekiwać, że będą działać zgodnie z tymi samymi ograniczeniami operacyjnymi, prawnymi lub regulacyjnymi, co główna linia produktów, aby ludzie mogli pominąć wszystkie zwykłe, nudne rzeczy. Celem jest maksymalizacja zainteresowania i zdobywania wiedzy a, nie martwienie się o odpowiednie testowanie, dokumentację lub zachowanie właściwych standardów kodowania. Mogą być nawet jako produktami “open source”, aby upewnić się, że firma nie będzie oczekiwała znaczącego przychodu z własności intelektualnej tych produktów i nie trzeba się będzie zbytnio martwić o wsparcie dla nich.

Celowe produkty poboczne wymagają zarządzania i struktury, nie są tylko odrobiną wolnego czasu dla pracowników na zabawę. Jakiś czas temu, gdy 20% budżet edukacyjny Google stał się modnym trendem powielanym przez organizacje, wiele firm spodziewało się, że otrzymają następnego Gmaila lub Mapy Google, inwestując w wolne piątkowe popołudnia. Szybko zdali sobie sprawę, że nie można po prostu skopiować części kultury innej firmy, a ludzie i tak nie są produktywni w piątkowe popołudnia.

Lepiej ustalić ramy czasowe i skupić się w 100% na budowaniu przez jakiś czas innego produktu, służącego do intensywnej nauki. Kilka dni to raczej za mało, kilka miesięcy to najprawdopodobniej za długo na taki wysiłek. Produkty żyjące zgodnie z cyklami rynkowymi mają spokojniejsze okresy. Wówczas ludzie kończą wdrażanie funkcji o niskim priorytecie, ponieważ chwilowo nie ma “krytycznych feature’ów”. Zamiast po prostu dodawać więcej złożoności do podstawowego produktu, co utrudnia jego użytkowanie i utrzymanie w imię wątpliwych korzyści (w końcu był powód, dla którego te pozostałe funkcje miały niższy priorytet), zrób sobie przerwę i stwórz coś zupełnie innego i ekscytującego.

Na przykład latem 2015 roku zrobiliśmy sobie przerwę od MindMup (w wakacje zwykle jest cicho) i eksperymentowaliśmy z budowaniem narzędzia do dokumentacji/testowania opartego na znacznikach. Skończyło się na dopracowaniu i wydaniu go na GitHubie, ale nie zyskało ono żadnej znaczącej popularności. Pozwoliło nam jednak poeksperymentować z wieloma metodami tworzenia pakietów JavaScript jak Webpack i NPM, a około sześć miesięcy później w oparciu o tę nową wiedzę znacznie uprościliśmy strukturę pakietów i wdrożeń dla naszego głównego produktu. Latem 2018 spędziłem kilka dni z dwoma kolegami budując Desole, system monitorowania wykorzystujący wszystkie kuszące nowe zabawki, które miał do zaoferowania AWS. Nigdy nie został poprawnie ukończony, ale dowiedziałem się wiele o usługach w chmurze, których potem używałem do innych rzeczy. I dostałem szansę poeksperymentować z AWS CodePipeline, którego teraz używamy dla wdrożeń MindMup.

Tworzenie wewnętrznych produktów deweloperskich jest często dobrym wyborem. Mają one zaletę poprawy dostarczania Twojego głównego produktu. Jeśli takie narzędzia rzeczywiście okażą się przydatne, możesz również wykazać się dobrą wolą i uzyskać darmowy rozgłos, wypuszczając je jako “open source”. W ten sposób powstały Bug Magnet i Appraise, które rozwiązały nudne i czasochłonne zadania, z którymi często mierzyliśmy się przy MindMup, a następnie zostały wystarczająco dopracowane do użytku zewnętrznego. Rozwijanie ich pozwoliło mi na zabawę z ekscytującą technologią - rozszerzeniami Chrome i automatyzacją testów z Puppeteer - których mogłem następnie użyć również w głównym produkcie. Czasami te rzeczy żyją własnym życiem i faktycznie przyciągają społeczność, tak jak Claudia.js (jest to prawdopodobnie najpopularniejsza rzecz, jaką kiedykolwiek opublikowałem na GitHub, przyniosła nie tylko pozytywny marketing dla naszego głównego produktu, ale nawet ktoś napisał o tym książkę). Oprócz tego, że pisanie sprawiało mi wiele radości, praca nad Claudia pozwoliła mi nauczyć się i wypróbować nowe funkcje języka JavaScript, które potem trafiły do ​​MindMup. Doprowadziło to również do sporej ilości zaproszeń na konferencje, na których mogłem promować nasz główny produkt.

Inną dobrą opcją jest zbudowanie czegoś zupełnie odrębnego, w innej domenie. Niech ludzie zrobią coś fajnego, czego zawsze chcieli spróbować. Podczas kolejnej wakacyjnej przerwy, zainspirowani doniesieniami Snowdena i serialem “The Man in the High Castle” na Amazon, pracowaliśmy nad grą wideo. Nazwaliśmy ją  East Germany 2020. Akcja toczyła się w alternatywnej osi czasu, w której mur berliński nigdy nie upadł, a Stasi prowadzi odpowiedniki Facebooka i Google, aby szpiegować świat. Pracowaliśmy nad tym przy użyciu najnowszych funkcji HTML5 przez około półtora miesiąca i zbudowaliśmy początkową grywalną wersję, a następnie porzuciliśmy ją na zawsze. Miałem nadzieję, że stworzymy z tego rzeczywisty produkt, ale wersja, którą zbudowaliśmy, działałaby tylko w najnowszej wersji Chrome, a prawdę mówiąc, gra nie była wciągająca. Wprowadzenie jej jako właściwego produktu zajęłoby miesiące dodatkowej pracy i wymagało przyzwoitego budżetu marketingowego, więc po prostu ją porzuciliśmy. Fajnie było budować, bo choć popełniliśmy mnóstwo błędów podczas eksperymentowania z nową technologią, to nie wpłynęły one na nasz główny produkt. Zachowaliśmy natomiast nową wiedzę, a pomysły, takie jak animacje SVG i schematy HTML5 Flexbox, trafiły później do MindMup i znacznie poprawiły wrażenia użytkownika.

Celowe tworzenie produktów pobocznych to świetny sposób na eksperymentowanie i uczenie się oraz wzbudzanie ekscytacji w pracy, gdy staje się zbyt nudna, ale może to być trudne do sprzedania organizacjom pod ciągłą presją czasu. Tak, oznacza to branie kilku tygodni wolnego na zbudowanie czegoś, co nie wiąże się z natychmiastowym zwrotem z inwestycji, ale taki sam efekt ma wprowadzanie niepotrzebnej złożoności czy niesprawdzonych bibliotek. Gdy złe decyzje techniczne trafiają do głównego produktu, usunięcie ich zwykle kosztuje znacznie więcej niż wyrzucenie produktu pobocznego i zachowanie wiedzy. A jeśli wyjdzie z tego coś dobrego, możesz niskim kosztem ulepszyć swój podstawowy produkt.

Wielkie podziękowania dla Paula Shephearda za inspirującą weekendową dyskusję, która doprowadziła do powstania tego posta.

Zdjęcie okładki Philipp Lublasser, Unsplash.