O tym jak nie “kraść“ będąc programistą
Wyobraź sobie taką hipotetyczną sytuację. Potrzebujesz aby ktoś pomalował twoją ścianę na biało i chcesz zamówić do tego fachowca. Dzwonisz na pierwsze lepsze ogłoszenie i zjawia się facet na oględziny. Mówi tak: “No... To ja bym tu użył nowej farby od ‘microcolors’. Jej jeszcze nie wypuścili oficjalnie na rynek, ale już ją można dostać. Podobno super się nią maluje. Kolega już raz pomalował i było ok. Tylko wyjdzie trochę drożej bo to specjalne rozpylacze trzeba dokupić. A... no i nie ma białej. Będzie lekko różowa, ale to lepiej, bo to warstwa zabezpieczająca przed parą. Będzie pan zadowolony.”
Czujesz, że coś jest nie tak. Prawda? Masz proste zadanie, i oczekujesz że zostanie wykonane solidnie, szybko i w miarę możliwości tanio.
Kiedy pytasz programistę, o to w jakich wymarzonych technologiach chciałby/chciałaby pracować, nikt raczej nie wspomina tych sprawdzonych, na których dobrze się zna. Każdy chce spróbować czegoś nowego. Kiedyś tak było z nie relacyjnymi bazami danych, następnie z architekturą opartą na aktorach no i oczywiście z mikroserwisami.
Wszędzie być musi AI ( Artificial Inteligence), ML (Machine Learning). Najlepiej jeszcze w powiązaniu z AR ( Augmentented Reality).
Tylko po co? Czy nie jest to czasem zwykła kradzież?
Trzeba powiedzieć sobie to otwarcie: “przekombinowujemy”. Często. Często ulegamy “Hype Driven Design” zamiast szukać najprostszych i najskuteczniejszych rozwiązań.
Zleceniodawca i wykonawca - para naszych bohaterów. Dla wygody nazwiemy sobie zleceniodawcę “Biznesem” (generalnie sponsor, stakeholder, właściciel), a wykonawcę “programistą” (choć mógłby to być architekt wdrożeniowiec, specjalista, czy zespół)
Pierwszą rzeczą jaką trzeba sobie uświadomić, to że obie strony mają zupełnie rozbieżne cele.
Programista oprócz oczywistego zarabiania pieniędzy, chce się przede wszystkim rozwijać, poszerzać kompetencje, pracować w interesującym projekcie z ciekawymi technologiami. Biznes natomiast chce najczęściej w projektach IT: zoptymalizować proces, wdrożyć nową usługę, zaistnieć na rynku z nowym produktem, a na końcu najczęściej zarobić lub zaoszczędzić pieniądze.
Czy więc jest szansa, żeby te dwa światy znalazły jakiś wspólny mianownik? Czy on w ogóle istnieje i czy należy go szukać?
Bądźmy szczerzy. Nie wszystkie zadania, których podejmują się programiści są wyzwaniem. Często są to tak zwane CRUD-y (Create, Read, Update,Delete), czyli programy w których dodajemy, modyfikujemy, czytamy i usuwamy jakieś obiekty( Na przykład CRUD dla drużyny piłkarskiej, pozwoli przechowywać listę nazwisk z jakimiś atrybutami i tą listę dowolnie modyfikować).
Dla kogoś, kto zrobił takich projektów kilka, kolejny staje się nudny i odtwórczy.
Gdzie tu jest cel programisty? Jaki w tym rozwój?
Moim zdaniem, o wiele łatwiej było by się dogadać, gdyby obie strony przyznały że mają takie, a nie inne cele i że są one różne. W końcu TO NIC ZŁEGO!
Nie chcemy kraść, a jednocześnie przygodę z nowymi technologiami trzeba gdzieś zacząć, więc w konsekwencji potrzebny jest kompromis. Zadania nudne i nie rozwijające będą nawet w najciekawszych projektach.
Osoba kierująca projektem, powinna go prowadzić tak, aby zaspokoić obie strony. Przecież jeśli programista nauczy się już nowej technologii, to przełoży się to na jego lepszą pracę w przyszłości. Z kolei jeśli “dowieziemy” funkcjonalności szybciej, będziemy mieli więcej zaufania i będziemy mogli poświęcić zyskany czas na coś ciekawego.
Jeśli skupimy się na tylko jednej stronie, to albo utkniemy w “wiecznym doskonaleniu kodu” przez programistów, albo programiści szybko się wypalą i odejdą z projektu.
Inaczej mówiąc: nie da się rozwijać produktu nie rozwijając ludzi i na odwrót!
“U siebie rób jak u siebie.”- słyszeliście takie stwierdzenie? “Kombinowanie” kończy się, kiedy rozumiemy po co projekt robimy i dla kogo.
Skończyły się też już czasy “klepania kodu” w oderwaniu od domeny. Im programista jest bardziej świadomy domeny produktu tym lepiej. I nie mówię tego po to, żeby powiedzieć jak biznes jest zły. Jako programiści mamy na to wpływ i sami możemy dążyć do poznania tych celów.
Wyobraźmy sobie że pracujemy nad dziesiątym CRUD-em w naszym życiu dla bliżej nieokreślonej klasy obiektu “A”.
Pracuje nam się fajnie? Przykładamy się do pracy?
A jeśli pracujemy nad dziesiątym CRUD-em w naszym życiu i są to dane o lądowaniu na marsie, które będzie wykorzystywał Elon Musk?
A jeśli pracujemy nad dziesiątym CRUD-em w naszym życiu dla pana Janka, który ma firmę rodzinną od 40 lat i potrzebuje zarządzać dostawcami mąki, żeby robić lepszy chleb?
A przecież praca dokładnie ta sama. Świadomość celu pomaga w motywacji. Nawet jeśli nie pracujemy nad lądowaniem na marsie, świadomość, że jest to komuś potrzebne buduje. Co ważne: moim zdaniem muszą o to zabiegać obie strony. Zarówno nasz “biznes” jak i my sami.
Całe stwierdzenie zabrzmiało dość górnolotnie, a idea jest prosta: ludzie powinni ze sobą rozmawiać i mieć pełny obraz sytuacji. Tylko tyle i aż tyle. Zadbajmy o to, żeby nie “okradać” pracodawcy z czasu, czy nie być z niego “okradani”, jeśli jesteśmy po tej drugiej stronie.
Jeśli się tak natomiast nie dzieje i zespół jest słabo zmotywowany, programiści znajdują sobie różne “utrudniacze” żeby się nie nudzić. Wynajdują technologie, w których jeszcze nie pracowali, a o których słyszeli że są fajne. Z nimi, zadanie pewnie potrwa trochę dłużej, bo programista będzie się uczył, ale dzięki temu zyska nową wiedzę, czyli spełni swój cel.
Można też stosować rozwiązania nie adekwatne do dziedziny problemu i na przykład do zwykłego CRUD-a zastosować pełen stos CQRS razem z event sourcingiem, kolejkami i asynchronicznością (są to bardziej skomplikowane wzorce i koncepcje architektoniczne). Generalnie wszystko co kryje się pod pojęciem “Hype driven Design”. Ogólnie proces takiego “przekombinowania” nazywa się overengineering. Taka “kradzież” z nudów też jest zła.
Sprawa komplikuje się jeszcze bardziej, w momencie kiedy bardziej zagłębimy się rozwój produktu w czasie. W rzeczywistości jest to dość skomplikowane. Prawdopodobnie pierwszym celem projektu IT jest jak najszybsze dostarczenie MVP (Minimum viable product), czyli minimalistycznej, pierwszej wersji projektu, żeby przetestować, czy zostanie on dobrze przyjęty, czy jest to dobry kierunek, czy uda się czerpać zyski, czy uda się wejść na rynek. W kolejnych fazach cel projektu się zmienia. Może to być lepsza wydajność, większa niezawodność, czy też lepszy UX (user expirience - wrażenia użytkownika).
Na pierwszych etapach zupełnie nie istotne jest na przykład, czy system obsłuży milion użytkowników na raz. My natomiast stosując “overengineering” o tym “pomyśleliśmy za wczasu” i już wdrażamy trudną i skomplikowaną architekturę. A tym czasem mamy prawie zerową pewność, że projekt w ogóle zaistnieje na rynku! Jest to zwykła strata czasu, której da się uniknąć. Na przykład tak, jak zrobiła to firma tworząca oprogramowanie Dropbox.
Wypuściła ona swego czasu film, gdzie prezentowała działanie swojej aplikacji. Otóż sęk w tym, że aplikacji jeszcze nie było!
Był to prosty sposób na zweryfikowanie, czy ludzie będą chcieli ich produktu. Można było wydać pieniądze na zbudowanie działającej wersji produktu, ale film okazał się równie skuteczny.
Czasem w projektach stosuje się podobną technikę. Przykładowo tworzy się przycisk do generowania raportów, po to, żeby sprawdzić czy ludzie będą z tego korzystać. Często stosując dodatkowo tak zwane testy AB, gdzie część użytkowników dostaje starą, część nową wersję oprogramowania, żeby sprawdzić zachowania na małej próbce(czyt. żeby nie musieć zbyt wielu ludzi przepraszać ).
Gdybyśmy nie wiedzieli o tym, jaki jest cel wdrożenia takiego przycisku, moglibyśmy spędzić nad nim wiele nikomu nie potrzebnych godzin, po to, żeby po kilku tygodniach dowiedzieć się, że całą funkcjonalność należy usunąć, bo nikt jej tak naprawdę nie chce. Strata dla programisty, bo czuje że wykonał niepotrzebną pracę i dla projektu, bo mógłby w tym czasie zyskać bardziej potrzebne funkcjonalności.
Żeby nie “kraść” musimy być świadomi tego, po co wdrażamy funkcjonalności.
W praktyce robienie MVP “na wczoraj” - to znaczy bez wzorców, bez przygotowania, również było by stratą! Kiedy zmieniły by się założenia, musielibyśmy całość kodu wyrzucić do kosza i zacząć od nowa. Jak sobie z tym poradzić?
Tak jak cele biznesowe będą zmieniać się w czasie, tak architektura naszej aplikacji powinna za nią podążać. Nie budujemy więc kompletnie nieprzemyślanego systemu. Budujemy go, aby można go zmieniać w przyszłości.
Po co jest architektura aplikacji, jeśli nie po to żeby wspierać nasze cele? Zatem skoro cele są zmienne, nasza architektura musi ewoluować w czasie. Na początku może to być zwykły “jedno warstwowy monolit” ( jedna z najprostszych, jednocześnie na dłuższą metę najmniej zdatnych do rozwoju i zmian architektur), potem może ewoluować w aplikację wielowarstwową, czy rozproszoną, w zależności od nowych celów projektu.
To, na co chciałbym tu zwrócić uwagę to, to że skoro będziemy modyfikować mocno nasz projekt, musi on być od razu na to gotowy. To oznacza że MUSI mieć dobre testy i jakość kodu od samego początku. Tu nie ma kompromisów.
Żeby nie trwonić czasu (czyli nie “kraść”), musimy dbać o testy i jakość kodu, a naszą architekturę dynamicznie dostosowywać do celów projektu!
Podobnie nie robienie pewnych rzeczy również jest złe. Na przykład nie robienie CI CD (Continous Delivery, Continous Integration - metody automatycznego testowania, pakowania i wdrażania aplikacji) na dłuższą metę to również “kradzież”. Jeśli twój zespół marnuje na to czas, to również powinieneś bić na alarm. Podobnie jeśli widzisz, że ktoś marnuje czas na w inny sposób - testy manualne, które da się zautomatyzować, czy inne manualne zadania, które można wyeliminować.
Nie traćmy czasu i eliminujmy powtarzające się zadania! Nie dajmy innym tracić czasu.
Everything should be made as simple as possible, but not simpler
W pewnej firmie stoi tablica cyfrowa. Ot tablica, po której ekranie można pisać specjalnym długopisem. Można przewijać obrazek, można wytrzeć ją ręką, można zmieniać kolory. Generalnie cud techniki. Ta tablica mnie fascynuje, bo choć nie wiem jaka jest jej dokładna cena, jestem przekonany że można było za nią kupić zapas flamastrów na kilka lat i kilka "zwykłych analogowych" tablic. Nie widzę w niej absolutnie żadnej przewagi względem zwykłej tablicy. Ale jest. Jest cyfrowa i świeci.
Podobnie w projektach IT również czasem da się spotkać takie, które nie są tak naprawdę potrzebne. Widziałem prezentację aplikacji AR ( Rozszerzona rzeczywistość), która wyświetlała raporty. Widziałem projekt aplikacji opartej o blockchain, która miała zliczać coś w rodzaju reputacji/karmy użytkowników (około 500 użytkowników). Widziałem też projekty oparte o ML (Machine Learning), gdzie ewidentnie lepiej sprawdziła by się statystyka, czy proste wzory.
Ktoś te projekty robił! Ktoś spędził część swojego życia tworząc te produkty!
Kiedy o tym myślę, wydaje mi się, że cel tych programistów został spełniony. Nauczyli się nowej technologi. Projekt był interesujący i odwalili kawał dobrej nikomu nie potrzebnej roboty.
Kiedyś ktoś mi powiedział, że istnieje różnica pomiędzy architektem aplikacji, a architektem rozwiązań. Ten drugi znajdzie najprostsze rozwiązanie, nawet jeśli to oznacza mniejszy zysk, albo nawet jego brak. Ktoś mógł krzyknąć, że raporty można równie dobrze wyświetlić na ekranie. Ktoś mógł zaimplementować zliczanie reputacji na zwykłej tabeli w bazie. Ktoś mógł zrezygnować z ML na rzecz statystyki. Świadomy programista moim zdaniem powinien być po części takim architektem rozwiązań. Powinien znaleźć prostsze rozwiązanie jeśli istnieje. W końcu jesteśmy leniwi! I jeśli nie ma sensu czegoś pisać, to po prostu nie róbmy tego!
Gdy jesteś programistą, myślisz o tworzeniu aplikacji. Podobnie kiedy masz super młotek, wszystko wydaje się być gwoździem. Aby jednak nie “okradać” naszych zleceniodawców lepiej zaproponować im faktycznie lepsze i bardziej dla nich dostosowane rozwiązanie. To zaprocentuje w przyszłości.
Szukaj NAJPROSTSZYCH rozwiązań, nawet jeśli nie obejmują one kodowania!
Jest wiele sposobów aby okradać pracodawcę. Można wynosić widelce, papier toaletowy, żarówki. Można spać w pracy, iść na trzy godziny na obiad, kombinować z L4, czy uczestniczyć w nieistotnych spotkaniach. My jednak jesteśmy ludźmi uczciwymi i chcemy dobrze wykonywać naszą pracę. Czasem nie jest to proste i łatwo wpaść w pewne pułapki zupełnie nieświadomie.
Jak nie “kraść “będąc programistą?
Mam nadzieję że po odpowiedziałem na to pytanie. Nie jesteśmy gwiazdami rocka, czy prima balerinami. Jesteśmy rzemieślnikami i starajmy się swoja prace wykonywać rzetelnie i być jak najlepszymi w tym, co robimy.