Funkcyjna obsługa błędów w Kotlinie i Javie

Czasem obsługa błędów jest prosta, „zerojedynkowa”: albo operacja się powiedzie, albo rzuci wyjątkiem. Mamy jednak też sytuacje, gdy od strony biznesowej podejście „wszystko albo nic” nie ma sensu i oczekiwane jest działanie w trybie „best effort”. Na wejściu jest zestaw danych, wykonujemy na nich operacje, jeśli w trakcie pojawiają się błędy, to po prostu idziemy dalej i próbujemy doprowadzić do końca tak wiele, jak się da, nie wycofując się z niczego. Nie mówimy o beztroskim ignorowaniu błędów: nawet jeśli zgadzamy się na częściowe niepowodzenie, dobrze jest wiedzieć, które z danych były przetworzone pomyślnie, a które z błędem. Jak zaprogramować takie podejście w sposób czytelny i jasno przekazujący intencję?

Imperatywne podejście (try-catch) w naturalny sposób modeluje sytuację zerojedynkową. Żeby zamodelować wersję „best effort” musimy myśleć w sposób bardziej funkcyjny, potraktować zarówno operację do wykonania jak i błąd jako byty na równi z danymi. Będziemy „kolekcjonować” błędy, żeby móc później zanalizować, ile ich było.

Języki nastawione na programowanie funkcyjne ułatwiają tu sprawę, ponieważ mają sprawdzone i dobrze opisane rozwiązania. Przykładowo Scala ma w bibliotece standardowej typ Try. Kotlin i Java nie są językami tradycyjnie wykorzystywanymi w sposób funkcyjny — nie oznacza to, że nie da się działać w nich w analogiczny sposób, jedynie to, że może być trudno znaleźć odpowiedź, jak do tego podejść.

Czytaj dalej „Funkcyjna obsługa błędów w Kotlinie i Javie”

Praca ze schowkiem z linii komend

Efektywna praca ze schowkiem systemowym to nie tylko umiejętność szybkiego wciskania Ctrl+C i Ctrl+V — przydatna jest też na przykład wiedza, jak korzystać ze schowka w terminalu.

Warto oglądać dobrych programistów przy pracy, pozwala to nauczyć się rzeczy, o których istnieniu po prostu nie wiemy. Ostatnio uderzyło mnie to przy słuchaniu prezentacji twórców Springa — w pewnym momencie Rob Winch potrzebuje zakodować hasło, a potem wkleić je w jedno pole w IDE (patrz 30-sekundowy fragment nagrania). Do tej pory gdy miałem zrobić coś podobnego, uruchamiałem komendę wypisującą coś w terminalu, zaznaczałem tekst myszą i kopiowałem. Upierdliwa rzecz, trzeba oderwać ręce od klawiatury, można kliknąć w złym miejscu, a z dala od biurka, na przykład na chodzącym jak spróchniała deska touchpadzie Lenovo, taka prosta czynność staje się utrapieniem. Natomiast Rob wykonał po prostu w terminalu:

spring encodepassword password | copy

Jak możemy uzyskać coś takiego na naszej maszynie? Sprawa jest nieco skomplikowana, bo nie ma jednej metody dla wszystkich systemów.

Czytaj dalej „Praca ze schowkiem z linii komend”

Dzielenie się testowymi klasami pomocniczymi w Gradle’u

Czasem mamy przypadek, że piszemy test jednostkowy jakiejś klasy i okazuje się, że część kodu testowego może być przydatna w innych częściach naszego projektu. Jak udostępnić ten kod, żeby był widoczny zarówno w testach aktualnego projektu, jak i w testach projektów od niego zależnych? Gradle od wersji 5.6 udostępnia dla tego celu plugin java-test-fixtures.

Czytaj dalej „Dzielenie się testowymi klasami pomocniczymi w Gradle’u”

Importy nieprzerywające pracy w IntelliJ

Do niedawna nienawidziłem przeklejania kodu do IDE. Nie dlatego, żebym uważał, że prawdziwemu programiście nie wypada robić copy-paste ze Stack Overflow (to bzdura). Cierpiałem na samą myśl, że będę musiał dodać importy do wszystkich użytych w tym fragmencie klas, ponieważ normalnie w IntelliJ jest to niewygodne. Dobra wiadomość: istnieje wbudowana opcja, która pozwala ułatwić sobie życie — ale domyślnie jest wyłączona. W dalszej części pokażę, jak ustawić swoje IDE do wydajnej pracy z importami. Na samym końcu będzie krótka dygresja o modelach mentalnych dla programistów.

Czytaj dalej „Importy nieprzerywające pracy w IntelliJ”

Poprawny Git commit message w IntelliJ

Pisanie commitów Gita wymaga zachowania pewnego savoir-vivre’u. Nie jest to powszechna wiedza, ale od czego mamy IDE? Oprócz wyłapywania potencjalnych błędów w kodzie mogłoby też kontrolować tekst wpisywany przy commicie. IntelliJ Idea (oraz WebStorm itp.) potrafi takie rzeczy — ale musimy włączyć odpowiednią opcję.

Czytaj dalej „Poprawny Git commit message w IntelliJ”

3 najbardziej pouczające materiały z 2019

Styczeń to na różnych stronach i blogach okres publikowania podsumowań minionego roku. Miałem zamiar napisać artykuł w stylu „3 najlepsze książki programistyczne, jakie przeczytałem w 2019”, ale okazało się, że nie zbiorę trzech: musiałbym albo zaproponować rzeczy, z których nie byłem w pełni zadowolony, albo książki niezwiązane ściśle z branżą IT. Zamiast tego mogę zaproponować 3 rzeczy związane z programowaniem, ale niekoniecznie wydrukowane na papierze: jedną książkę, jedną publikację w sieci i jedno nagranie wideo.

Czytaj dalej „3 najbardziej pouczające materiały z 2019”

Niebezpieczny isEmpty() z utili Springa

Wyobraźmy sobie, że znajdujemy w projekcie taki kod w Javie (lub prawie identyczny — w Kotlinie):

public void assertNoViolations(Collection<ConstraintViolation> violations) {
    if (!isEmpty(violations)) {
        throw new IllegalStateException("violates constraints: " + violations);
    }
}

Na oko — kod jak kod, robi co trzeba, nuda. Co może pójść nie tak?

Metoda zgodnie z oczekiwaniami bezproblemowo akceptuje nulla. Rzuca wyjątkiem, gdy przekażemy jej listę zawierającą contraint violations. Jest jeden szkopuł:

assertNoViolations(emptyList());
java.lang.IllegalStateException: violates constraints: []

Jak to jest możliwe?

Czytaj dalej „Niebezpieczny isEmpty() z utili Springa”

Testy kontraktowe: Pact bez Pact Brokera

pact-jvm to jeden z dwóch wiodących frameworków do pisania testów kontraktowych dla Javy i JVM. Problemem na wejściu może być znalezienie sposobu na dzielenie się kontraktami: oficjalnie polecanym rozwiązaniem jest serwer Pact Broker, napisany w Rubym. Postawienie serwera trochę ułatwia dostępność obrazu dockerowego, ale wciąż całość wymaga nieco zabawy. Jeśli chcemy na szybko sprawdzić, czy Pact nam się podoba, wolelibyśmy opcję wymagającą minimalnego nakładu pracy.

Tu pojawia się możliwość rzadko wspominana w tutorialach Pacta: wymiana kontraktów przez repozytorium Mavena, nawet takie lokalnie na dysku. Nie potrzebujemy niczego poza narzędziami, które i tak mamy programując w Javie.

Czytaj dalej „Testy kontraktowe: Pact bez Pact Brokera”
Creative Commons License
Except where otherwise noted, the content by Piotr Kubowicz is licensed under a Creative Commons Attribution 4.0 International License.