W chwili gdy piszę te słowa, ITCandidateEvaluator nabrał ostatecznego kształtu – osiągnąłem dokładnie to co zamierzałem, aplikacja chodzi bez zauważalnych błędów i może być z powodzeniem wykorzystana zgodnie ze swoim przeznaczeniem. Zatem… czy to już koniec?
(Spoiler Alert!) „Prawie”
Ostatni wpis zakończył się na tym, że program już działał – wyświetlał to co trzeba i jak trzeba, tylko nie zapisywał nigdzie zmian. No i kod był trochę nieczytelny – z tym też musiałem sobie jakoś poradzić. Podsumujmy zatem co się wydarzyło w projekcie od tego czasu:
1.Refaktoryzacja
Posprzątałem trochę w klasach i metodach, wyodrębniłem duplikaty, usunąłem niepotrzebne wstawki i komentarze zostawione samemu sobie. Poprawiłem nazewnictwo niektórych zmiennych i metod, poprzestawiałem funkcje tak „aby było aby”*.
(*) jest to jedna z porad zawartych w książce „Czysty kod”, że sekwencja w której napisane są metody powinna dać się opisać słówkiem „aby”. Np.
stwórzObiektKandydatNaPodstawieJegoCV(){
//aby to zrobić muszę odpalić kolejno metody:
- stwórz Listę Nazw Plików w podanym katalogu
- usuń z nazw plików rozszerzenia
- usuń z nazw plików inne znaki niż litery
- usuń z nazw plików tagi typu 'CV' albo 'resume'
- odseparuj od siebie imię i nazwisko
//aby to zrobić muszę odpalić poniższą metodę na każdym elemencie listy:
-włóż spację pomiędzy mały znak i duży łapiąc przy okazji wyjątki
- stwórz obiekty kandydatów na podstawie otrzymanych wartości
}

2.Storage Strategy
Następnie przyszła pora na sprawienie aby aplikacja w końcu zaczęła zapisywać zmiany. Zrobiłem to na szybko za pomocą serializacji obiektów Recruitment do pliku. O ile sama serializacja nie sprawia problemów, o tyle deserializacja jest ryzykowna i w łatwy sposób pozwala dobrać się do kodu potencjalnemu hakerowi. ITCandidateEvaluator jest jednak zbyt nieznaczącym tworem aby komukolwiek chciało się w to bawić, więc i ja nie chciałem poświęcać na to więcej czasu niż potrzeba.
Jednocześnie postawiłem na wzorzec strategii, bo użytkownik będzie miał do wyboru serializację do zwykłych plików na dysku, ale również do obiektów typu BLOB w bazie danych.
Choć o SQL już trochę czytałem, to dopiero teraz miałem okazję wykorzystać bazy danych w praktyce. O dziwo – poszło to zaskakująco gładko: najpierw postawiłem serwer MySQL, potem podpiąłem go pod IntelliJ, dodałem odpowiedni ’connector’ w Mavenowym pliku pom.xml i już mogłem dodawać, usuwać i modyfikować rekordy. Na chwilę obecną nie chciałem jeszcze robić wszystkiego samemu, dlatego z każdą pierdołą latałem do Chata GPT i we dwójkę błyskawicznie ogarnęliśmy temat.

Aktualnie jestem w trakcie lektury kolejnej książki z serii Rusz głową!, tym razem właśnie o SQL-u i o tym też chciałbym stworzyć jakieś teksty, ale jeszcze nie mogę podać konkretnych terminów.
3.Logger
O log4j – bibliotece zawierającej chyba najpopularniejszy dziennik zdarzeń w Javie, uczyłem się jeszcze na kursie CodeGym. W końcu nadarzyła się okazja aby z tego skorzystać.
Zadaniem loggera jest zapisywanie zdarzeń w programie, albo bezpośrednio w konsoli albo w osobnych plikach tekstowych. Kawałek takiego loga wygląda u mnie tak:
[2024-02-25 13:08:43] [INFO ] [AWT-EventQueue-0] [Model] - A new Presets object has just been created.
[2024-02-25 13:08:43] [WARN ] [AWT-EventQueue-0] [Model] - The selected name: (1-20 characters) is already taken.

Dzięki temu można sprawdzić sekwencję zdarzeń w aplikacji i dowiedzieć się np. dlaczego dany obiekt jeszcze nie został zainicjalizowany i dostajemy NullPointerException. Oprócz wiadomości typu INFO dostajemy też np. WARN i ERROR pozwalające dociec co nie tak poszło w programie.
4.JavaDoc
O ile zostawianie po sobie zwykłych komentarzy jest w oczach doświadczonych programistów traktowane jak zaśmiecanie kodu, o tyle stworzenie porządnej dokumentacji to objaw troski o kolegów zespołu i pragnienie stworzenia przewodnika, który oszczędzi im sporo czasu na rozkminę o co autorowi chodziło.
W ITCandidateEvaluatorze dokumentację, i owszem – stworzyłem. Czy dobrą? Wątpliwe. Czy poprawną? Chyba tak. Ale z pewnością lepsza taka niż żadna.
Nie sądzę, żebym kiedykolwiek miał okazję rozwijać ten projekt w zespole, ale już całkiem możliwe, że samemu zechcę do niego wrócić za rok albo dwa, kiedy będę miał znacznie więcej do powiedzenia jako programista. Wtedy z pewnością docenię tę dokumentację, którą po sobie zostawiłem:

5.Docker
Docker jest niezmiernie popularnym systemem konteneryzacji projektów. To obszerny temat, ale na chwilę obecną warto sobie rzecz przyrównać do zgrywania płyt CD do plików .ISO które uskuteczniało się na masową skalę na początku tego millenium. Chodzi o to, że tworzymy obraz płyty i możemy go wtedy odpalić w odpowiednim programie nie mając nawet czytnika CD.
I tak samo tutaj – odpowiednio skonstruowany obraz projektu możemy odpalić nie mając IDE, bazy danych, czy nawet wymaganej wersji systemu operacyjnego.
Chciałem dodać Dockera do swojego projektu, ale wyszło na to, że GUI Swinga po prostu się gryzie z tą opcją, dlatego temat ugrzązł w martwym punkcie. Jednocześnie Docker wydaje się zbyt ważnym narzędziem, aby tak po prostu go zostawić, a ponadto moja przygoda ze Swingiem już się raczej zakończyła. Dlatego prędzej czy później i tak postaram się ogarnąć kontenery, a co sam się dowiem, tym i tutaj z chęcią się podzielę.

The end?
Prawie. Zostało jeszcze jedno bardzo ważne zadanie – napisanie testów jednostkowych. Co prawda wszystkie funkcjonalności przetestowałem manualnie wzdłuż i wszerz w trakcie pisania aplikacji, ale utwierdzenie się w przekonaniu, że program robi co powinien to nie jedyna zaleta testów automatycznych.
Druga, może nawet ważniejsza, to sprawienie aby kod nie bał się zmian. Teraz, kiedy wszystko jest gotowe, zwyczajnie nie chcę już gmerać w metodach żeby przypadkiem czegoś nie spie..zepsuć. A to nie jest dobre.
Dobry kod nie powinien bać się ulepszeń.
Dobrze zdaję sobie sprawę, że pracując nad komercyjnym projektem muszę go tworzyć w taki sposób, żeby w dowolnej chwili można tam było wdrożyć zażyczone sobie przez klienta poprawki. W tym celu powstała i jest stosowana przez profesjonalistów metodologia TDD – Test Driven Development i styl pracy:
Red -> Green -> Refactor
W skrócie – deklarujemy metodę, piszemy test który ma przejść i dopiero wtedy bierzemy się za implementację owej metody aż dojdziemy do momentu w którym test „się zazieleni” (tzn. „jest ok”). Teraz możemy brać się za upiększanie kodu jak nam się podoba – jeśli coś zwalimy to od razu test nam o tym powie.
Choć na TDD jeszcze jestem za chudy w uszach, to bez podstawowych testów wstyd będzie pokazać projekt pierwszemu lepszemu programiście.
Ale o tym dopiero w kolejnym odcinku serii…