Zasady programowania

Wstęp

Do napisania tego artykułu zainspirowała mnie niedawno przeczytana książka “Zasady” Raya Dalio. Ray opisuje w niej zasady, którymi kieruje się w życiu oraz w pracy. Dzięki nim osiągnął wielki sukces oraz znalazł się w tym miejscu, w którym aktualnie jest.

Zauważyłem, że ja również mam zbiór reguł, którymi kieruję się podczas kodowania. Postanowiłem je spisać, bo zachęca do tego sam autor książki. Wierzę, że znajdziesz wśród nich coś wartościowego dla Ciebie.

Programowaniem pasjonuję się mniej więcej od 1998 roku. Większość opisanych przeze mnie zasad stosuję od zawsze, poniekąd intuicyjnie. Wiele z nich jest dla mnie po prostu naturalne. Gdy natykam się na sformalizowany opis którejś z moich zasad, to jestem zdziwiony, że w ogóle można działać inaczej. Prawdopodobnie ta naturalność w ich stosowaniu wynika z indywidualnych cech mojego charakteru.

Dlatego zdaję sobie sprawę, że moje reguły nie będą pasować każdemu. Dla wielu osób mogą okazać się zbyt trudne do stosowania lub nawet bezsensowne. Nic w tym złego. To nie jest poradnik, a jedynie opis tego co działało u mnie. Co pozwoliło mi odnieść sukces w programowaniu. Uważam, że warto poznać różne punkty widzenia, bo to jest coś co nas rozwija i procentuje w przyszłości.

Podzieliłem zasady na dwie kategorie: techniczne i dotyczące zespołu oraz na dotyczące współpracy z biznesem. W tych pierwszych zawarłem również takie z pogranicza administracji systemami/devops. Podejście w którym programista jest blisko infrastruktury i utrzymania systemów jest dla mnie naturalne. Wierzę, że taka organizacja pracy przynosi dużo korzyści i jest po prostu lepsza. Natomiast zasady współpracy z biznesem poruszają tematy angażowania się w kluczowe obszary firmy. Uważam, że nie warto zamykać się w swojej technologicznej bańce. W końcu w firmie chodzi o zarabianie pieniędzy, a one najczęściej są gdzie indziej – technologia, kod, czy aplikacja to tylko narzędzia.

Główną ideą wszystkich moich zasad programowania jest to, że firma jest najważniejsza. Wynikają z tego takie elementy jak automatyzacja, zastępowalność, spójność, czytelność, niezależność. Myślę, że będzie to dostrzegalne w opisanych przeze mnie regułach.

Zapraszam do lektury!

Ważne info. Gdy używam słów „firma” oraz „biznes”, mam na myśli firmę, dla której wytwarzasz oprogramowanie. Która zajmuje się jego utrzymaniem, zarabia dzięki niemu i która płaci Ci pieniądze. W swojej zawodowej karierze zdecydowanie bardziej wolałem pracować dla firm posiadających i rozwijających własny produkt. Stąd moje zasady bardziej tam pasują. W przypadku software house’ów sytuacja jest trochę bardziej skomplikowana, bo „firm” może być kilka. Niemniej dostosowanie opisanych reguł do takiego układu nie powinno być dla Ciebie dużym wyzwaniem.

Zasady techniczne i dotyczące zespołu

Automatyzuj powtarzalne czynności.

Jeśli robisz tą samą rzecz drugi raz, to powinna zapalić się czerwona lampka. Zanim zrobisz to trzeci raz, zakoduj automatyzację. Dotyczy to zarówno samego procesu kodowania jak i implementacji funkcji biznesowych. Automatyzacja ma wiele istotnych zalet:

  • oszczędza czas
  • nie myli się (a człowiek tak, wykonując dziesiątki razy te same czynności)
  • może zostać wykorzystana przez kogoś innego
  • może zostać rozbudowana lub wykorzystana w innym miejscu

Przykładem automatyzacji podczas kodowania było u mnie napisanie prostego skryptu w SQL. Generował on gotowy kod klasy w C#, która była mapowana na tabelę w bazie danych. Dzięki temu tworzenie kodu do istniejących tabel było dużo szybsze. Dodatkowo eliminowało ryzyko literówek podczas wpisywania nazw.

Pisz kod nie wymagający Twojej pracy w utrzymaniu.

Może to być nazwane “dobrym lenistwem”. Chodzi o to, żeby tworzyć bezobsługowe oprogramowanie. Jeśli wystąpi błąd to nie zamykasz aplikacji, tylko dajesz możliwość ponowienia operacji. Jeśli aplikacja wymaga restartu raz dziennie, to nie robisz tego ręcznie. Używasz toola do restartowania (albo najlepiej likwidujesz przyczynę konieczności restartów). Gdy ktoś z biznesu prosi o wyciągniecie specyficznych danych z bazy danych – dajesz mu narzędzie. Takie, którym sam może wygenerować odpowiedni raport. Gdy nie będziesz tak działać, spodziewaj się wielu tasków tzw. “wrzutek”, odciągających cię od właściwej pracy.

Opiszę przykład z jednej z firm, w których pracowałem. Gdy zaczynałem, napisane już było narzędzie do importowania plików XML. Problem w tym, że było konfigurowane w całości w kodzie – dla każdego typu pliku. Typów pliku było bardzo dużo oraz się często zmieniały. Powodowało to wysyp tasków dla programisty oraz konieczność częstych wdrożeń nowej wersji aplikacji.

“Dobre lenistwo” oraz pragnienie automatyzacji skłoniły mnie do napisania czegoś lepszego. Powstał tool, w którym można było zapisać mapowanie struktury pliku na nasz, znany format. Odbywało się to za pomocą skryptu w Pythonie. Dzięki temu można było testować i wykorzystywać różne konfiguracje bez wdrożeń i zmian w kodzie.

Aplikacja powstała w weekend, po godzinach pracy i bez taska (mój oddolny pomysł). W efekcie spowodowała ogromny wzrost szybkości importu nowych plików. Później zaowocowała nawet stworzeniem osobnego stanowiska a następnie działu w firmie. Pracownicy tego działu zajmowali się głównie pisaniem skryptów mapujących. Narzędzie, w praktycznie niezmienionej formie, pozostawało w użyciu przez 7 lat.

Nie rób dwa razy tego samego błędu.

Błędy podczas tworzenia kodu są naturalne i będą zawsze występować. Każdy je robi i trzeba to wkalkulować w proces wytwarzania oprogramowania. Natomiast błędy, które się powtarzają wiele razy to poważny problem.

Gdy wystąpi błąd zawsze staram się znaleźć osobę odpowiedzialną oraz przyczynę błędu. Szukanie “winnego” ma tylko jeden cel – poprawę procesu. W żadnym wypadku nie chodzi o atakowanie, czy upokarzanie innej osoby, W wielu przypadkach wyciągam temat na forum publiczne (nawet jeśli to ja zrobiłem błąd), po to aby wszyscy mogli się czegoś nauczyć.

Osoba, która zrobił błąd zawsze powinna przeanalizować to, co doprowadziło do wystąpienia problemu. Poza oczywistą poprawą, należy też wykonać czynności, które zminimalizują szanse na wystąpienie tego samego błędu w przyszłości. Czasem są to zmiany w kodzie, czasem doczytanie i douczenie się czegoś. Jeśli przyczyną była niewiedza, to porządne zgłębienie tematu (omówione poniżej) jest tutaj bardzo wskazane.

Zarówno u mnie, jak i w moim zespole ta metoda sprawdzała się bardzo dobrze. Dzięki niej, sytuacje, w których soft ciągle się “sypie” były niezwykle rzadkie.

Używaj gotowych bibliotek.

Gotowe biblioteki są super, bo ktoś je napisał i przetestował. Istnieje też spora szansa, że nie zawierają poważnych błędów. O oszczędności czasu chyba nie muszę wspominać. Z drugiej strony nadużywanie obcego kodu też może być problemem. Trzeba robić aktualizacje, dbać o kompatybilność, przeważnie trudno jest wprowadzić własne zmiany.

Ja jestem zwolennikiem zdrowego rozsądku. Kiedy napotykam problem, który jest popularny i całkiem spory, to bez zastanowienia szukam gotowej biblioteki. Przykłady? Parsowanie CSV, szyfrowanie, logowanie błędów, obsługa dostępu do bazy danych itp. Na szczęście koduję głównie w .NET, który wiele funkcji ma wbudowanych we framework. W znaczący sposób ułatwia to pracę.

Własny kod piszę w 2 przypadkach:

  1. Problem jest mało popularny. Biblioteki najczęściej też wtedy nie są popularne. Pisane przez pojedyncze osoby a co za tym idzie narażone na posiadanie wielu błędów.
  2. Problem jest popularny ale prosty i szybki w implementacji. Nie chcę zaśmiecać projektu dziesiątkami zewnętrznych modułów. Dla prostych problemów, rozwiązanie zazwyczaj bywa częścią większej biblioteki i niestety trzeba dołączyć masę nieużywanego kodu.

Nigdy nie używaj kodu, którego działania nie znasz i nie rozumiesz.

Wiele razy spotykałem się z sytuacją, gdy ktoś skopiował kod z Internetu. Najczęściej sprawdził tylko na szybko, czy działa i oddał zadanie jako wykonane. Później okazywało się, że jednak coś nie do końca działa a “autor” nie umie tego nawet poprawić.

Nigdy tego nie robię. Nigdy nie oddałem kodu, którego nie zrozumiałem w 100%. Oczywiście, że wiele razy skopiowałem kod z Internetu. Jednak w takich przypadkach zawsze analizowałem go linijka po linijce. Dopiero gdy byłem pewny, że wiem jak działa, wrzucałem do projektu.

Jeśli widzę w gotowym kodzie użycie jakiejś wbudowanej funkcji, której działania nie znam, zawsze sprawdzam jej dokumentację. Jeśli widzę użycie jakiegoś parametru, którego nie znam, sprawdzam w dokumentacji, do czego służy. Dzięki takiemu podejściu ciągle uczę się nowych rzeczy. Minimalizuję też ryzyko wystąpienia błędu we wklejanym kodzie.

Ta zasada dotyczy również kodu z tego samego projektu, napisanego przez innego programistę.

Pamiętaj, że bierzesz odpowiedzialność za swój kod. Jeśli użyjesz takiego, który ma poważną dziurę (np. bezpieczeństwa), możesz narazić swoją firmę na problemy. Późniejsze tłumaczenie się tym, że to nie twoja wina, bo wziąłeś kod z Internetu i go nie przejrzałeś, nie będzie świadczyć o Tobie zbyt dobrze.

Dogłębnie poznaj tematy techniczne.

Nie wystarczy, że coś działa, jeśli nie rozumiesz dlaczego działa. Ucz się, czytaj, analizuj, szukaj informacji. Do momentu aż będziesz w stanie z całą pewnością powiedzieć, że wiesz jak działa dana rzecz. Nie robiąc tego stoisz w miejscu jeśli chodzi o rozwój. Dodatkowo może to powodować, że będą do Ciebie wracać ciągle te same problemy. Bo umyka Ci jakiś detal.

Oczywiście niektóre rzeczy można przyjmować jako pewniki i nie ma potrzeby ich analizować. Wraz z doświadczeniem będziesz mieć w głowie coraz więcej takich pewników. Możesz je wykorzystać np. do szybszego poznania innych technologii.

Jakiś czas temu przeglądarka Chrome zmieniła sposób obsługi ciastek. Wymagało to przeróbek w wielu miejscach w kodzie by użyć dodatkowego parametru. Zmiana była prosta i działała. Można powiedzieć, że to taki task „no-brainer”. Dla mnie natomiast było to za mało. Pamiętam dobrze, że spędziłem wtedy kilka godzin na czytaniu dokumentacji i analizowaniu jak w przeglądarkach działają ciastka. Dowiedziałem się (i co ważniejsze, zrozumiałem) wielu ciekawych rzeczy, które w przyszłości “kliknęły” i pozwoliły mi dużo szybciej rozwiązać podobne problemy. Dzięki eksperckiej wiedzy mogłem też uciąć kilka pomysłów biznesowych. Z pełnym przekonaniem wiedziałem co mówię i nikt nie musiał tego sprawdzać (np. marnując czas programisty).

Pisz kod dopasowany do już istniejącego.

Ta zasada jest bardzo ważna w zespole. Zdarza się, że do projektu wchodzi nowa osoba, przyzwyczajona do innego stylu kodowania. W dodatku nie chce się dostosować. Pisze po swojemu, dodaje swoje ulubione biblioteki, chociaż w projekcie są inne robiące to samo. Zaczyna nawet zmieniać działający kod pod swoje przyzwyczajenia. Jeśli to Ty jesteś taką nową osobą, to nie rób tak.

Najważniejsza jest spójność. Dzięki temu dużo łatwiej jest zrozumieć kod. Wiadomo też bez dogłębnego czytania, czego można się po nim spodziewać.

Jeśli w jednym miejscu aplikacji jest coś zrobione w sposób A, a w drugim, coś podobnego w sposób B, to mamy problem. Gdy przyjdzie kolejna osoba z podobnym zadaniem, będzie się zastanawiać co powinna zrobić. Jest szansa, że skończy się to nowym sposobem C. A to już duży problem.

Ja zawsze dostosowuję się do kodu, który już istnieje. Nawet jeśli wiąże się to z koniecznością korzystania ze starszych bibliotek lub brakiem jakichś nowych funkcji.

Jeśli jesteś nową osobą w projekcie to gwarantuję Ci, że mocno zapunktujesz w zespole, jeśli będziesz stosować tę zasadę.

Korzystaj z istniejących elementów, zamiast pisać swoje od nowa.

Zasada jest trochę powiązana z poprzednią, ale bardziej dotyczy funkcji biznesowych.

Załóżmy, że masz za zadanie zakodować ekran edycji jakichś danych. Są tam różne pola: tekstowe, do wyboru daty, jakiś checkbox. Do tego lista elementów z możliwością dodawania i usuwania. Pierwszą rzeczą, jaką powinieneś zrobić jest poszukanie w aplikacji istniejącego ekranu, który wygląda i działa podobnie. Po co? Właśnie po to, żeby nie wymyślać wszystkiego samemu. Dużo lepiej jest użyć czegoś co zostało już zrobione. Pamiętaj, spójność jest najważniejsza. Uławia zrozumienie kodu i utrzymanie go w porządku. Do tego użytkownicy będą Ci wdzięczni, bo dostaną ekran wyglądający tak jak coś co już znają.

Zasada dotyczy zarówno elementów interfejsu jak i np. algorytmów. Jeśli masz zrobić eksport do pliku CSV, to najpierw szukasz czy gdzieś w projekcie jest już taki eksport zrobiony. A co w przypadku, gdy znajdziesz kilka takich miejsc i w każdym jest inny kod? Wtedy najlepiej zapytać się, kogoś bardziej doświadczonego, co z tym zrobić.

Dzięki tej zasadzie dużo łatwiej jest też uzasadnić, dlaczego napisałeś taki a nie inny kod. Podczas review, na pytanie, czemu to tak zrobiłeś, możesz odpowiedzieć: “W taki sam sposób było to już zrobione w innym miejscu”. Pokazujesz, że czytasz kod i starasz się dopasować. A to dobra cecha programisty w zespole.

Nie bój się pytać.

Niewiedza i proszenie o pomoc bardziej doświadczonych członków zespołu nie jest złe. Ale warto wcześniej się wysilić i spróbować znaleźć rozwiązanie samemu. “Jak mam to zrobić?” albo “Nie umiem tego zrobić. Pomożesz?” nie są najlepszymi pytaniami. Dlaczego? Bo pokazują, że się wystarczająco nie postarałeś. Dużo lepiej wygląda coś takiego:

  • “Przeszukałem Internet i znalazłem, tylko to i to, potrzebuje jeszcze pomocy w tym i tym”,
  • “Znalazłem w projekcie podobną funkcję w dwóch miejscach ale w obu jest zakodowana inaczej. Na której wersji mam się wzorować?”

W takich przypadkach pokazujesz, że się starasz i robisz wszystko co w Twojej mocy. Jednak dochodzisz do momentu, gdzie potrzebujesz konkretnego wsparcia.

Na koniec jeszcze dwa błędy, które można popełnić:

  • zbyt długie zwlekanie z pytaniem,
  • brak pytania i kodowanie według własnego “wydaje mi się”, gdy masz wątpliwości

Pierwszy najczęściej skutkuje słabą wydajnością. Drugi wracaniem tasków, bo są źle zrobione.

Myśl o tym jak można zepsuć swój kod.

Jedna z moich ulubionych zasad. Rzadko ją widuję u innych ludzi. Wynika bardzo mocno z moich cech charakteru i wrodzonych umiejętności. Wielu programistów niestety testuje tylko “ścieżkę sukcesu”, czyli scenariusz, w którym wszystko idzie zgodnie z planem. Nie bierze natomiast pod uwagę “dziwnych” sytuacji, które w praktyce zdarzają się jednak całkiem często.

Podczas programowania, na chwilę wciel się w rolę złego hackera, który będzie próbował zepsuć Twój kod. Pomyśl o nietypowych danych wejściowych, nietypowych parametrach metody i o tym co się może wtedy stać. Weź też pod uwagę np. ogromne ilości danych jakie miałby przetworzyć Twój kod. Często jest tak, że kod działa dobrze i szybko na małej ilości danych, a na dużej ma problemy.

Dzięki temu już na etapie pisania programu możesz znaleźć i poprawić wiele błędów. W innej sytuacji wiele z nich wyszłyby dopiero podczas testów lub dużo później na produkcji. Stosując tę zasadę, Twój kod będzie lepszy i rzadziej będziesz musiał go poprawiać.

Szczególnie warto tutaj zwrócić uwagę na:

  • wartości null, które mogą przyjść jako parametr,
  • wyjątki/błędy podczas wykonywania operacji I/O (czytanie z dysku, request do zewnętrznego serwisu itp.)
  • skrajne i ekstremalne wartości parametrów
  • ekstremalnie dużo danych np. w kolekcji czy tablicy
  • puste kolekcje/tablice

Pamiętaj, że poprawa błędu na etapie kodowania jest dużo mniej kosztowna dla firmy niż poprawa tego samego błędu już po wdrożeniu. Warto starać się tworzyć kod jak najwyższej jakości.

Pisz kod tak, żeby zrozumiał go ktoś, kto dopiero wchodzi do projektu.

Zasada ta często jest trudna do realizacji dla początkujących programistów. Umiejętność przychodzi naturalnie z czasem, wraz ze wzrostem doświadczenia. Możesz sprawdzić jak to wygląda u Ciebie, analizując swój kod np. sprzed pół roku.

Podstawowe rzeczy o których trzeba pamiętać:

  • używanie języka angielskiego
  • właściwe nazewnictwo (samoopisujący się kod)
  • używanie nazwanych zmiennych zamiast liczb/napisów/wartości wprost w kodzie
  • podział na mniejsze funkcje/metody zamiast jednego wielkiego bloku kodu
  • spójność z istniejącym kodem
  • używanie standardowych wzorców
  • używanie popularnych bibliotek
  • trzymanie się konwencji danego frameworka/biblioteki
  • opieranie własnych rozwiązań o podobne schematy jak w popularnych bibliotekach

Nie powtarzaj się (DRY).

Jedna z najbardziej znanych i najlepiej opisanych zasad programowania.

  • Nie powielaj kodu.
  • Jeśli musisz zrobić kopię jakiegoś kodu, wydziel go do osobnej funkcji/metody i wywołaj z obu miejsc.
  • Używaj klas by “zamknąć” w nich wydzieloną logikę
  • Używaj nazwanych zmiennych/stałych zamiast wartości wprost w kodzie

Zaletą jej stosowania jest przede wszystkim łatwość wprowadzania zmian. Do tego dochodzi możliwość szybkiego znalezienia wszystkich miejsc wykorzystania danego kodu.

Analizuj kod. Zgłaszaj błędy.

Jest to rozwinięcie zasady “Myśl o tym jak można zepsuć swój kod” oraz “Nigdy nie używaj kodu, którego działania nie znasz i nie rozumiesz” na kod innych programistów.

Uważaj, gdy wprowadzasz jakieś zmiany w kodzie napisanym przez drugą osobę. Powinieneś traktować wszystkie miejsca na które wpłynęła Twoja zmiana, jak Twój kod. Jeśli czegoś nie rozumiesz, wykonuj głębszą analizę. Aż do momentu gdy będziesz pewny, że wiesz jak działa dany fragment programu.

Gdy znajdziesz błąd zgłoś go. Jeśli jest prosty do poprawy, to po konsultacjach z autorem, możesz go poprawić. Staraj się nie wprowadzać poprawek bez konsultacji. Istnieje szansa, że możesz czegoś nie wiedzieć i zepsuć poprawnie działający element systemu.

Pełne zrozumienie działania kodu zazwyczaj pomaga podjąć właściwą decyzję. Sprawia też, że masz większą wiedzę o projekcie, co przekłada się na wyższą pozycję w zespole.

Poznaj infrastrukturę.

Zainteresuj się środowiskiem produkcyjnym. Dowiedz się jak jest skonfigurowane, jakie są różnice między nim a środowiskiem testowym czy developerskim. Zdarza się, że pewne rzeczy na testach są uproszczone lub zrobione “na skróty”. W konsekwencji, kod dobrze działający na środowisku testowym, może źle działać na produkcji. Świadomość różnic między środowiskami pomaga odpowiednio wcześnie zareagować i wyeliminować błędy.

Jestem zwolennikiem podejścia DevOpsowego. W jego założeniach programista odpowiada zarówno za napisanie dobrego kodu, jak i poprawne wdrożenie go na produkcję. Niemniej, możesz pracować w firmie, gdzie te dwa obszary są od siebie zupełnie odseparowane. Nie zmienia to faktu, że szczegółowe poznanie środowiska produkcyjnego w znaczący sposób zmniejszy liczbę problemów z Twoim kodem po wdrożeniu.

Zapisuj historię i twórz backupy.

Ludzie zawsze coś zmienią albo usuną przez pomyłkę. Zapisuj historię edycji danych (wraz z datą zmiany oraz autorem). Nie usuwaj rekordów z tabeli tylko oznaczaj odpowiednią flagą. Dzięki temu zawsze możesz odzyskać dane i w wielu przypadkach oszczędzić komuś mnóstwo czasu. A do tego zyskać prawdziwą wdzięczność współpracownika, czy klienta.

Rób (lub zleć zespołowi operacyjnemu) cykliczne backupy wszystkich ważnych danych. Nigdy nie wiesz, kiedy spłonie serwerownia hostująca Twoją aplikację. Sprawdzaj, czy backupy odtwarzają się prawidłowo. Miej przygotowany plan i procedurę odtworzenia krytycznych elementów systemu z backupu.

W skrajnych przypadkach brak backupów może doprowadzić do upadku i zamknięcia całej firmy.

Myśl o wydajności.

Podczas pisania kodu, zastanów się, jak zadziała pod dużym obciążeniem oraz podczas przetwarzania dużej ilości danych. Najczęściej na lokalnym komputerze lub na środowisku testowym nie widać problemów wydajnościowych. Powodem może być niewielka testowa baza danych czy ograniczona liczba jednoczesnych użytkowników. Po wdrożeniu na produkcję, okazuje się jednak, że warunki są zupełnie inne.

Poznaj algorytmy i struktury danych o złożoności obliczeniowej niższego rzędu. Stosuj je w miejscach, w których potencjalnie będą przetwarzane duże ilości danych. Jeśli w pętli sprawdzasz czy jakiś element występuje w tablicy lub liście, to prawdopodobnie powinieneś tę listę zastąpić słownikiem czy HashSetem. Takie struktury które mają złożoność obliczeniową wyszukiwania rzędu O(1).

Pamiętaj jednak, że zmniejszenie złożoności obliczeniowej najczęściej powoduje wzrost złożoności pamięciowej. Czyli przyspieszasz kod i zmniejszasz zużycie procesora kosztem większego zużycia pamięci.

Innym częstym błędem jest przetwarzanie dużych plików, wczytując je najpierw w całości do pamięci. W takim przypadku stosuj czytanie strumieniowe – fragment po fragmencie. Jeśli musisz zagregować dane, możesz plik przeczytać kilka razy. W wielu przypadkach będzie to lepsze rozwiązanie niż wczytanie całości do pamięci. A w niektórych sytuacjach może okazać się jedynym sposobem, który w ogóle zadziała.

Twórz interfejs dla ludzi “nietechnicznych”.

W wielu przypadkach podczas tworzenia aplikacji na wewnętrzny użytek firmy, nie korzysta się z pomocy specjalisty od UI/UX. Po prostu polega się na tym, co wymyśli programista. Pamiętaj, że użytkownicy często są osobami mało technicznymi. Dbaj o czytelność, przejrzystość i spójność interfejsu w całej aplikacji. Gdy stosujesz ikony, koniecznie dodawaj dymki (tooltipy). To że dla ciebie dana grafika jest oczywista, nie oznacza, że jest tak samo dla innej osoby.

Używaj powszechnie znanych elementów interfejsu, które mają jasno określoną funkcję. Do pola wyboru zdecydowanie lepiej użyć checkboxa niż listy rozwijalnej z wartościami “tak” i “nie”.

W celu inspiracji warto zerknąć na znane aplikacje dużych firm. Możesz także skorzystać z gotowych bibliotek UI. Pozwalają one na szybką budowę dobrze wyglądającego interfejsu.

Projektuj system pod rozbudowę.

Staraj się przewidywać, które elementy systemu mogą być w przyszłości rozbudowywane. Włóż więcej wysiłku w ich zaprojektowanie. Bardzo mocno pomaga tutaj zasada angażowania się w tematy biznesowe. Jeśli masz odpowiednią wiedzę, to dużo łatwiej będzie ci wskazać takie miejsca w aplikacji. Możesz też dopytać biznesu, czy planuje w przyszłości rozszerzać dany element, czy raczej to co robisz jest jednorazowym zadaniem.

Może okazać się, że jakiś fragment systemu jest rozbudowywany, a wcześniej nic na to nie wskazywało. W takiej sytuacji poświęć więcej czasu na refaktoryzację i dostosowanie kodu do kolejnych zmian. Jest spora szansa, że za chwile pojawią się nowe wymagania w danym obszarze.

Loguj błędy i procesy.

Logowanie jest krytycznym i niezbędnym elementem każdego systemu. W wielu przypadkach bez odpowiednich logów na środowisku produkcyjnym, znalezienie i odtworzenie błędu na lokalnej instancji jest praktycznie niemożliwe. Absolutnym minimum jest logowanie wszystkich błędów na produkcji. Bez tego nawet nie dowiesz się, że coś nie działa w aplikacji. Po zgłoszeniu błędu przez użytkownika być może nie będziesz w stanie go potwierdzić a co dopiero powtórzyć.

Jednym z najpoważniejszych błędów jest łapanie wszystkich wyjątków i pomijanie ich logowania. Czasem spotyka się takie rozwiązanie, bo ktoś chciał w ten sposób “wyciszyć” fragment kodu. Problem jest jednak taki, że nie masz pojęcia, jak często dany błąd występuje. Nie zauważysz także pojawienia się innego, np. dużo poważniejszego.

Jeśli chodzi i logowanie procesów to warto zapisywać wszystkie ważne operacji biznesowe, które dzieją się w systemie. W wielu przypadkach nie ma żadnych błędów a jednak biznes zgłasza, że “coś nie działa”. Często jedyną opcją, okazuje się wtedy dokładne prześledzenie logów biznesowych. Gdy ich nie ma, pozostaje próba powtórzenia błędnego działania na lokalnym lub testowym środowisku, co nie zawsze się udaje.

Zasady dotyczące współpracy z biznesem

Proś o doprecyzowanie. Nie wymyślaj funkcji biznesowych.

Nie da się przewidzieć i zaplanować wszystkiego. Wiele problemów wychodzi dopiero na etapie kodowania. Jeśli czegoś nie wiesz lub jest niejasne nie wymyślaj rozwiązania samemu. Prowadzi to tylko do błędnego kodu, który wraca i musi być poprawiony.

Skracaj ścieżkę procesową. Nie bój się rozmawiać z osobami z biznesu. Powiedz z czego wynika problem i zapytaj jak dana funkcja powinna działać. Bardzo często zdarza się, że są to tematy mocno techniczne i biznes nie będzie umiał odpowiedzieć. Zaproponuj swoje rozwiązanie, uprzedź o wszelkich konsekwencjach i poproś o wybór.

Bądź transparentny jeśli chodzi o wynik tego co zakodujesz. Nie ukrywaj żadnych potencjalnie złych rezultatów. One i tak się prędzej czy później pojawią. Decyzja powinna zawsze wychodzić od biznesu. Powinna być podjęta, po przekazaniu przez ciebie wszystkich istotnych informacji. Dobrze przeprowadzona rozmowa ściąga z ciebie odpowiedzialność za źle działające funkcje. Oczywiście, jeśli działają źle przez złe wymagania a nie przez złą implementację.

Proponuj rozwiązania problemów jeśli są prostsze/szybsze/lepsze.

Osoby z biznesu często nie są biegłe w sprawach technicznych. Mają jakiś problem i wymyślają rozwiązanie, które jest ograniczone wiedzą jaką posiadają. Zdarza się, że takie rozwiązanie jest dalekie od optimum. Ale ty wiesz, że w bardzo łatwy sposób można je ulepszyć. Nie bój się w takich sytuacjach proponować zmian. Biznes zazwyczaj się zgadza, o ile problem rzeczywiście zostanie rozwiązany. Często w takich przypadkach można przepchać jakiś bardziej uniwersalny mechanizm, który w pierwotnej wersji był szczególnym przypadkiem, dotyczącym konkretnego problemu.

Bezkrytyczne akceptowanie i kodowanie wszystkich wymagań, “jak leci” nie jest dobre. Bardzo często prowadzi do trudnego w utrzymaniu kodu i skomplikowanego systemu.

Angażuj się w tematy biznesowe.

Zasada ta, jest rozwinięciem poprzedniej i jest przeze mnie najczęściej stosowana.

Zainteresuj się biznesem, który prowadzi Twoja firma. Dowiedz się jak zarabia pieniądze, skąd bierze klientów. Poproś o dostęp do najważniejszych metryk, na podstawie których są podejmowane decyzje. Część firm, niestety traktuje programistów jak robotników i będzie Ci ciężko uzyskać wymienione informacje. Ja zawsze unikałem takiej pracy, bo nie dawała mi odpowiedniego poziomu satysfakcji. Zawsze chciałem być częścią biznesu, bo tam są pieniądze i największe możliwości.

Ostatnie kilka lat spędziłem w firmie, gdzie miałem dostęp do bardzo wielu danych. Mogę powiedzieć, że mocno zmienia to sposób w jaki podchodzi się do programowania. Nie myślisz tylko o dobrze napisanym kodzie i testach. Bardziej o tym, jak to co właśnie zrobiłeś realnie wpływa na biznes. Z wielką satysfakcją możesz obserwować, jak funkcja, którą napisałeś, spowodowała wzrost przychodów o kilka procent.

Działając w ten sposób, poznajesz i zagłębiasz się w tematy biznesowe. Zaczynasz bardziej rozumieć po co w ogóle kodujesz dane rzeczy. Ta wiedza w wielu przypadkach mocno przydaje się podczas programowania. Pozwala na dużo wcześniejszym etapie wyłapać błędy lub znaleźć słabe strony jakiegoś pomysłu. Programista zaangażowany w biznes i rozumiejący go, to bardzo cenna osoba na pokładzie firmy. Bardzo często też dobrze wynagradzana.

Szczerze polecam takie podejście, bo w przeciwnym wypadku programowanie często przeradza się w zwykłe “klepanie kodu”. W efekcie po jakimś czasie powoduje zmęczenie, frustrację i wypalenie zawodowe.

Nie uzależniaj od siebie firmy.

Spotkałem się z sytuacją gdy pracownik robi wszystko by być niezastąpionym. Wydaje się to kusząca perspektywa, ale ma też swoje wady:

  • wszystko musisz robić samemu
  • występuje ryzyko pracy po godzinach
  • na urlopie jesteś cały czas pod telefonem

Ja natomiast preferuję i polecam podejście zupełnie odmienne. Jak najmniejsze powiązanie firmy z konkretną osobą. Uważam, że jest to najbardziej uczciwa i w dłuższej perspektywie najbardziej korzystna dla obu stron sytuacja. Główne założenia, które warto zrealizować:

  • Wszystkie konta są zakładane na firmowy adres email (a najlepiej alias/grupę mailową, do której przypisani są programiści),
  • Wszystkie hasła znajdują się w menadżerze haseł,
  • Wszyscy programiści stosują się do zasady pisania zrozumiałego kodu
  • Cykliczne dzielenie się wiedzą
  • Rozwijanie jednej funkcji przez co najmniej 2 różne osoby
  • Automatyzacje. Brak konieczności robienia czegokolwiek ręcznie.

Możesz wykonać mały eksperyment myślowy. Zastanów się jak wielkim problemem byłoby dla firmy, gdybyś jutro zniknął. Oczywiście nie bierz pod uwagę swojego doświadczenia i umiejętności. Jedynie wszystkie rzeczy, które zależą od Twojej obecności w firmie. W idealnej sytuacji, firma nie powinna znacząco odczuć takiej sytuacji.

Rzetelnie wyceniaj zadania.

Nie zaniżaj ani nie zawyżaj wycen. Gdy nie jesteś pewien lub brakuje Ci danych powiedz o tym i zrób dokładniejszą analizę. Gdy zadanie wydaje się bardzo proste, istnieje spora szansa, że nie bierzesz wszystkiego pod uwagę.

Nie mów “nie da się”. Lepiej używać sformułowań “to bardzo trudne”, “zajmie to dużo czasu”. Nie bój się sporych wycen. Pamiętaj, że decyzję o realizacji danego tematu podejmuje biznes, między innymi na podstawie szacowanych kosztów. Lepiej gdy rzetelnie wycenione, czasochłonne zadanie nie zostanie podjęte, niż wycena będzie za niska a praca się przedłuży.

Biznes często nie ma problemu z tym, że coś może zająć sporo czasu. Ma natomiast problem, gdy zadanie nie jest “dowiezione” na zadeklarowany czas.

Nie muszę, chyba wspominać, że celowe zawyżanie wycen, by mieć więcej wolnego czasu nie jest najlepszym pomysłem. Wbrew pozorom można to całkiem łatwo wykryć a konsekwencje mogą nie być przyjemne.

Myśl o kosztach. Wybieraj rozsądne rozwiązania.

Często zdarza się, że programiści nie myślą o kosztach przy podejmowaniu decyzji technologicznych. Baza danych nie daje rady? Zwiększmy plan w chmurze. Aplikacji brakuje pamięci? Dokupmy więcej RAMu. Procesor obciążony na 100%? Zmieńmy maszynę. Niestety wszystko to kosztuje pieniądze. Często jest też tak, że problemy występują chwilowo a opłaty są stałe i przez większość czasu zasoby się po prostu marnują. Dla zwykłego pracownika może to nie ma znaczenia, ale patrząc z perspektywy firmy, już tak.

Dlatego zawsze warto poznać przyczynę a dopiero później podjąć odpowiednią decyzję. Być może jakieś niedawne zmiany w kodzie spowodowały problem. Być może ktoś popełnił błąd i wystarczy go poprawić. A może da się rozdzielić zasobożerne aplikacje na oddzielne maszyny? Rozwiązań może być wiele i nie koniecznie te najszybsze i najbardziej oczywiste są tymi najlepszymi.

Zawsze należy mieć też na uwadze koszt alternatywny. To, ile będzie kosztowało poprawienie lub zmiana kodu czy architektury. Załóżmy, że obciążenie serwerów rośnie powoli i zaczyna dochodzić do granic. W takiej sytuacji bardzo często nie da się dokonać prostych (i tanich) zmian, które powodują znaczącą poprawę. Dokupienie zasobów ma wtedy jak najbardziej sens.

Z drugiej strony, gdy w krótkim czasie następuje skokowy wzrost obciążenia to problem zazwyczaj leży gdzie indziej. W takiej sytuacji najkorzystniejszym rozwiązaniem zazwyczaj jest po prostu analiza i poprawa kodu lub architektury.

Umiejętność odpowiedniego zbalansowania kosztów, wydajności i czasu przeznaczonego na development, jest bardzo cenna i pożądana. Zwłaszcza w niewielkich firmach, czy startupach.

Podsumowanie

Spisałem w tym artykule 25 zasad, którymi kieruję się w swoim programistycznym „życiu”. Zdaję sobie sprawę, że nie są one dla każdego. Wierzę jednak, że ich stosowanie procentuje, a co za tym idzie, zwiększa szansę na szybki rozwój kariery programistycznej.

A ty, masz jakieś zasady, które stosujesz w programowaniu? Koniecznie podziel się nimi w komentarzu!

5 komentarzy

  1. Z jednej strony początkowo wszystkie rady wyglądają dobrze, jednak z drugiej dawniej nie było tylko porad i zasad a programy wydawały się lepsze. Zauważyłem że im więcej dobrych praktyk tym gorzej dla finalnego produktu i odbiorcy. Programy pisane samemu bez schematów działały dobrze ale z czasem wprowadzenia różnych „dobrych praktyk” naroiło się multum głębokich błędów i nieporozumień.

    1. Nie wiem co rozumiesz przez „dawniej”, ale ja stosuje wiele z tych zasad od ponad 20 lat. Część „odkryłem” jak byłem nastolatkiem (kodowałem wtedy w BASICu na Commodore 64) i pamiętam, że całkowicie zmieniły moje patrzenie na programowanie. Wielu początkujących programistów w dzisiejszych czasach robi te same błędy co ja kiedyś, skąd ten artykuł. Nie uważam, że te zasady jakoś negatywnie wpływają na finalny produkt. Wręcz przeciwnie. Taki produkt staje się bardziej przewidywalny, łatwiejszy w utrzymaniu i rozwoju. Programy pisane „samemu bez schematów” mają taki problem, że często tylko sam autor potrafi je później utrzymywać – i to tylko w najbliższej przyszłości. Bo jak wróci do kodu np. za pół roku to już nie pamięta co i jak. A to jest duża niedogodność przy pracy zespołowej.

  2. Ja sporo czasu spędziłem z biznesem analizując procesy i dopiero później siadałem do kodu. W większości przypadków z moimi klientami po prostu nie dało się inaczej, a z czasem bardzo to doceniłem i nie chce inaczej. Twoje porady są jak moja praktyka 🙂 No i też zaczynałem w BASICu, tylko że na ATARI.

  3. Co jeśli ktoś chce abyś był jego mentorem i pomagał mu/nadzorował jego już zaczęty projekt,
    kontynuując go, naprowadzając na lepsze rozwiązania?

Skomentuj

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Scroll to Top