5 najczęstszych problemów z kodem – interview Junior Java Web Developer

Wstęp

Miałem ostatnio okazję brać udział w rekrutacji lub skanowaniu potencjalnych kandydatów na stanowisko Junior Java Developer. Część z tych osób skończyło jakieś bootcampy lub masę innych kursów programistycznych. Niestety mimo upływających lat stwierdzam, że masowe kursy online/bootcampy zostały z wiedzą, jaką przekazują, w tym samym miejscu, w którym były 4 lata temu. Jest jeszcze parę mankamentów związanych z CV oraz ew rozmową z potencjalnym pracodawcą, ale
o tym napiszę na końcu. Przedstawie 5 najczęstszych problemów z kodem jakie namierzyłem podczas code review podczas procesu rekrutacji.

Poniższe przykłady dotyczą głównie projektów rozwijających serwisy webowe (REST)

w springu.

#1 Struktura projektu odzwierciedlająca typ klas, a nie domenę.

Naprawdę to nie jest trudne, a daje jasny sygnał, że rozumiesz, o co chodzi w podziale aplikacji na obszary biznesowe. Często jednak czy to w treściach kursów, czy w obrębie repo kandydata, spotykam upakowanie wszystkich klas domeny (z wszystkich domen) w jednej paczce, tak samo serwisy obsługujące wszystkie domeny też lądują w paczce services.

Struktura katalogów projektu ze względu na typ elementów

Lepszym rozwiązaniem jest ustawienie paczek ze względu na domenę.
Jeżeli idziesz w kierunku pisania mikroserwisów, taki podział to pierwszy krok do wydzielenia fragmentu logiki biznesowej do jednego serwisu. Natomiast pytanie, dlaczego taka, a nie inna struktura projektu, kończy się zazwyczaj głuchą ciszą.

Struktura katalogów projektu ze względu na domenę

#2 Zapewnienie zależności poprzez adnotację @Autowire

Już nawet IntelliJ z zainstalowaną obsługą springa (wersja płatna), pokazuje, że to nie jest najlepszy pomysł. Wynika to z faktu, że nie daje to pewności utworzenia obiektu
w kontenerze springa i może zaowocować pojawieniem się wyjątku NullPointer’a.

Zapewnianie zależności poprzez adnotację @Autowire

Metodą stosowaną w świecie projektów webowych pisanych Springu jest wstrzykiwanie zależności poprzez konstruktor. Dodatkowe atuty takiego rozwiązania to m.in. łatwiejsza testowalność, bezpieczniejszy i czystszy kod. Jeżeli nie chcesz pisać za każdym razem konstruktora, możesz podeprzeć się biblioteką lombok, która daje możliwość wytworzenia obiektu z wszystkich podanych pól poprzez adnotację @AllArgumentConstructor.

Wstrzyknięcie zależności poprzez konstruktor

#3 Złamanie podstawowego podejścia REST w konstrukcji ścieżki mapowania

Zazwyczaj spotykam się z taką konstrukcją /api/user/getUser lub jej wariacją. Wyciąganie usera po jego identyfikatorze najpierw powinno wskazać zasoby, które w podejściu REST oznacza się przez liczbę mnogą. /api/users/…., (może być więcej niż jeden user). Następnie przy użyciu identyfikatora wskazujemy, którego usera chcemy “wyciągnąć” z zasobów /api/users/{userId}.
Tej podstawowej wiedzy nie miało także kilku kandydatów z doświadczeniem sugerującym, że są już na poziomie tzw. regulara.podanych pól poprzez adnotację @AllArgumentConstructor. Więcej na temat nazewnictwa w formule REST znajdziecie tutaj.

#4 Operacje na obiektach domenowych wewnątrz kontrolera

Od pierwszych tygodni pracy, moi bardzo doświadczeni koledzy uczyli mnie, że kontroler restowy jest jak maszyna rozpakowująca. Powinna wywołać metody (raczej nie bezpośrednio z repozytorium ani domen), które zwracają obiekty potrzebne do realizacji odpowiedzi zapytania http. Bardzo często spotykam się wśród rekrutowanych juniorów lub początkujących regularów bezpośrednie wywołanie z repozytorium, a nawet operacje na elementach domenowych!!!!
Zasada jest prosta. Wołamy metody, które wytworzą nam obiekty będące składowymi generowania response. Tylko tyle i aż tyle.

#5 Nazewnictwo metod i klas

Po pierwsze język angielski. Na interview się zdarza z rzadka, jednak na grupach ludzi aspirujących do bycia juniorem jest to częstsze. Próby i nauka na prostych przykładach nie obejmują tego punktu. Chcę zwrócić uwagę na projekty w portfolio, trzymane na popularnych serwisach opartych o git’a. Pisanie kodu po polsku (mimo poprawnej logiki w kodzie) działa na Twoją niekorzyść!!!
Po drugie nazwy klas i metod muszą mieć jakieś znaczenie. Nazwijmy poprawnie obiekty domenowe. Nadajmy metodom nazwy, które jasno określają wykonywaną czynność.
Przy małych projektach możesz nie zauważyć bonifikaty z tego podejścia, jednak przy pracy produkcyjnej, gdzie mierzymy się z setkami klas i tysiącami linijek kodu, jest to kluczowe! Dobre nazewnictwo ułatwia czytanie kodu, poruszanie się po nim i analizę przepływu informacji.

Przykład

Wysyłamy pieniądze z naszego konta na inne.

W klasie kontrolera najpierw pobierane jest konto użytkownika, następnie sprawdzane jest czy są tam wymagane środki. Kolejnym krokiem (jeżeli środki są) jest pobranie numeru konta na które wysyłamy środki, przemapowanie odpowiedzi na nazwę banku tego konta. Możemy teraz dopisać tytuł przelewu. Jeżeli wszystkie dane są wprowadzone poprawnie następuje wysłanie pieniędzy.

Ubogie nazewnictwo:

AccountController
>> getAccount(userId)
>> check(accountId)
>> checkMoney(amount)
>> getAccountNumber(number)
>> createDescription(string)
>> send

Bogatsze / czytelniejsze nazewnictwo:

AccountController
>> fetchPrimaryAccount(userId)
>> validateAccountOwnership(accountId)
>> isBalanceInsuficient(amount)
>> creditorBankValidator(creditorAccountNumber)
>> attachTransferDescription(string)
>> executeMoneyTransfer(amount, creditorAccountId)

Załóżmy, że nie znasz historii przykładu. Nawigujesz tylko w swoim IDE. Zaczynasz od AccountControllera i zagłębiasz się w proces płatności. Który z wymienionych ścieżek z różnym nazewnictwem szybciej daje odpowiedź, co tak naprawdę się dzieje pod spodem?

To już tyle na temat błędów. Do następnego wpisu! @Darek

2 myśli na temat “5 najczęstszych problemów z kodem – interview Junior Java Web Developer

  1. Endorocket Odpowiedz

    Znajomość DDD już na stanowisko Juniora bez doświadczenia wymagane obecnie? (a propos #1)

    • admin Autor wpisuOdpowiedz

      DDD nie jest wymagane na stanowisko Juniora, Trochę za szeroko pojechałem w tym wątku :). Raczej chodzi o to, że większość projektów jakie miałem okazję widzieć/współtworzyć już implementuje DDD (hexagonal arch.).
      Natomiast sama struktura katalogów nie jest DDD, byłoby to straszne uproszczenie. Jednak jak kandydat potrafi w ten sposób dzielić pakiety to dużo łatwiej się pracuje z jego kodem. To takie moje prywatne zdanie na ten temat.
      Daje to jakąś przewagę, choćby w czytelności. Pewnie błąd to nie jest i tutaj się zagalopowałem. Dzięki @Endorocket za komentarz.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *