Wpis z mikrobloga

Mirki! Wrzucam, z gorącą prośbą o code review, kolejną wersję apki (swojej pierwszej aplikacji w ogóle), Time Keeper. Patrz: GitHub. Zasadniczo, jest to prosty timer/czasomierz, z możliwością tworzenia i eksprotowania listy zadań do pliku. Aplikacja zbudowana jest z użyciem JavaFX API, bez dodatkowych frameworków, chociaż dodanie obsługi Hibernate do przechowywania informacji o zadaniach i SQLowej bazy danych nie powinno stanowić wielkiego problemu.

Od końca maja, kiedy ogłaszałem się z tym samym (tu dzięki dla @moriturius za pomoc!), zrezygnowałem z używania TableView do wyświetlania listy zadań, na rzecz własnej kontrolki, przepracowałem też podstawowe klasy dla aplikacji - przy okazji rozpoczynając naukę JUnit i TestFX, przeniosłem projekt do Gradle'a i - long story short - próbowałem się jak najwięcej nauczyć.

Kilka przemyśleń natury ogólnej. Zbyt długa praca nad jednym projektem, szczególnie jeśli pracuje się samemu, nuży i z czasem trochę zniechęca - mam już jednak pomysły na dwa następne projekty* Testy to genialna sprawa! Zauważyłem, że klasy, które pisałem już próbując TDD wychodziły nawet o 30% krótsze niż pierwsze podejścia bez testów, jednocześnie zachowując pełną funkcjonalność. I jeszcze jedno, pisanie testów do istniejącego kodu jest uciążliwe i trochę, w moim odczuciu, jest przypinaniem kwiatka do korzucha.

JavaFX to niestety wciąż niedopracowane, średnio udokumentowane i czasem mega irytujące API. Przykład: pole tekstowe (TextField) ma domyślnie dodane menu kontekstowe, które otwiera się prawym kliknięciem. I tu parę problemów: nie można się dostać do elementów menu, żeby je np. spolszczyć, albo usunąć. A i całkiem wyłączyć menu - mi się nie udało, ale może za słabo szukałem - też nie jest je wcale prosto... Bo co taka metoda o nazwie onContextMenuRequest() może wywoływać... no cóż na pewno nie ma nic wspólnego z otwieraniem menu kontekstowego i w żaden sposób nie daje możliwości skonsumowania eventu, który menu otwiera... Takich grzybków jest niestety sporo. Niestety aplikacja wygląda też inaczej pod Windowsem a inaczej w Linuskach. Czcionki renderują się lepiej w okienkach, okno u pingwina...

* 1. Konsolowy odtwarzacz audio z filmików YT, żebym mógł sobie puszczać przez SSH muzykę z RaspberryPi podpiętego do HiFi :-) i 2. Klient i serwer czatu bez zbędnych fajerwerków (ale z bazą userów itd.).

Wołam: #programowanie #java #javafx #naukaprogramowania #odzeradodevelopera
  • 19
@TakToJestKontoMulti: Używasz Windowsa? Wersja hard:
1. ściągnij i zainstaluj Git'a - link
2. odpal Git Bash i wpisz git clone https://github.com/Kitke/time-keeper.git
3. otwórz konsolę w pobranym folderze time-keeper (shift + prawy click - Otwórz wiersz poleceń tutaj, czy jakoś tak) i wpisz gradlew build jar
4. W folderze build/libs odpal plik jar. Wymaga zainstalowanej najnowszej Javy.

Wersja light: jak sobie nie poradzisz wrzucę plik jar na GitHub'a :-)
@lerner: Jeszcze raz dzięki. Praca samemu z literaturą/internetem nie zawsze uczy właściwej metodologii pracy przy projekcie, także Twoje wskazówki są dla mnie szczególnie cenne.

Chociaż nie jestem w żaden sposób przywiązany do JUnit (ani żadnej innej technologii), chcę ją ogarnąć ze względów praktycznych. Niemniej jednak od przybytku głowa nie boli, chętnie spojrzę na Spock'a.
@kitke:

Tego typu rzeczy:


if (settings.playSounds()) {
    settings.setPlaySounds(
false);
else {
    settings.setPlaySounds(
true);
}
```możesz uprościć jako:```
settings.setPlaySounds(!settings.playSounds());

-----

https://en.wikipedia.org/wiki/Dependency_injection – staraj się nie inicjować obiektów w środku innych obiektów. Tzn masz np SettingsWindow, w środku inicjujesz Stage, FXMLLoader i Scene => to zabija testowalność i konfigurowalność. Nie możesz tego zmockować, klasa SettingsWindow robi „dużo rzeczy”, bo musi umieć tamte sobie przygotować do pracy.

Powinieneś mieć jedno
@MacDada: Dzięki za cenne uwagi! Uncle Bob'a czytam regularnie (mam książkę, śledzę blog i wykłady na YT) - jak zwykle problem jest z przełożeniem wiedzy na praktykę.

Jeśli chodzi o klasę App, to faktycznie jest za duża i jej rozbicie może dobrze zrobić.

Łączenie Stringów jest niestety mało eleganckie w takiej formie, ale na tyle na ile orientuje się w API, nie ma metody, która pozwoliłaby to zrobić 'czyściej'. Można w