poniedziałek, 29 września 2014

Warsjawa 2014, czyli ja jako prowadzący 2 warsztaty

W tym roku miałem okazję poprowadzić 2 warsztaty na Warsjawie. Wcześniej prowadziłem jedynie prezentacje (czy to w pracy czy na WrocławJUG), a w formie warsztatów to był mój pierwszy raz! I od razu 2 różne tematy!

Jak mi poszło? Uważam, że co najmniej dobrze. Wydaje mi się, że nie miałem większych potknięć, feedback zbierany od uczestników jest jak dotychczas pozytywny.


Podobne opinie słyszałem, gdy się podpytywałem uczestników, jak i przeczytałem w e-mailach. Pewnie coś więcej będę mógł się dowiedzieć (zwłaszcza liczę na uwagi krytyczne, aby wiedzieć co poprawić następnym razem), gdy uczestnicy wypełnią ankietę pokonferencyjną. Wszelakie e-maile i komentarze również mile widziane.

A tymczasem zamieszczam poniżej materiały z których korzystałem.

Upiększ swoje testy! Testowanie jednostkowe dla średniozaawansowanych.



Kod używany na warsztacie: https://github.com/mstachniuk/SolarSystem

Poznaj lepiej swoje srodowisko programistyczne i zwieksz swoja produktywnosc z IntelliJ Idea.

Kod napisany przez uczestników podczas warsztatów: https://github.com/mstachniuk/WarsjawaCodingDojo

Co do samej konferencji, to minusy (z punktu widzenia prelegenta):
- nie do końca przygotowane sale (rzutnik, nasłonecznienie, jakieś pudła)
- system do komunikacji z uczestnikami nie wysyła załączników i wiadomości nie dochodzą do wszystkich
- nie do końca udany pomysł ze szwendaniem się po knajpach po konferencji

A na plus:
- obecność zagranicznych spikerów
- wcześniejsza rejestracja dla prelegentów
- transparentnosć, co ile kosztowało
- długie przerwy, dobry timeline

I oby tak dalej, albo i jeszcze lepiej!

czwartek, 11 września 2014

Rusza rejestracja na tegoroczną Warsjawę oraz moje tematy

Już niedługo (21.09.2014 21:00) ruszy rejestracja dla uczestników Warsjawy - darmowej konferencji, która składa się z samych warsztatów! Liczba miejsc jest ograniczona, dlatego warto się spieszyć, zwłaszcza, że jest szansa na warsztaty, które będzie prowadził Venkat Subramaniam! Jest to założyciel Agile Developer, autor wielu książek jak i świetny prelegent, którego mieliśmy okazję wielokrotnie oglądać na polskich konferencjach. Styl jego prezentacji jest specyficzny, a o części jego wystąpień można przeczytać na moim blogu.

Dzięki wizycie Venkata w Warszawie, udało się go zaprosić także do Wrocławia i poprowadzi on wykład Programming with Lambda Expressions w ramach WrocJUG. Będzie również warsztat: Programming Concurrency - Workshop, ale na niego nie ma już miejsc, a lista oczekujących jest długa.

Jednocześnie zapraszam na warsztaty, które sam będę prowadził w ramach Warsjawy. Poniżej przedstawiam tematy, które będę prowadził, wraz z krótkim komentarzem.

Czas: Piątek, 26 września 2014 13:00
Temat: Upiększ swoje testy. Testowanie jednostkowe dla średnio zaawansowanych

Opis: Warsztat jest przeznaczony dla średniozaawansowanych programistów Java, którzy napisali już trochę testów i chcieliby je upiększyć. Podczas warsztatu będziemy ćwiczyć tworzenie ładnej sekcji given (za pomocą Builder'ów), jak i czytelniejsze zapisywanie assercji (za pomocą Hamcrest'a, FEST'a i AssertJ). Bedzie jeszcze o testowaniu wyjątków i testach parametrycznych. Warsztat będzie prowadzony po polsku, względnie może być po niemiecku;) Wymagane jest zabranie ze sobą własnego komputera ze skonfigurowanym środowiskiem programistycznym i opcjonalnie konto na GitHub'ie (do przesyłania gist'ów).

Być może, jak starczy czasu, będzie można poćwiczyć jeszcze inne rzeczy, ale to już zależy głównie od prędkości grupy, jak i zainteresowania tym, co będą chcieli usłyszeć uczestnicy.

Czas: Sobota, 27 września 2014 16:00
Temat: Poznaj lepiej swoje środowisko programistyczne i zwiększ swoją produktywność z IntelliJ Idea

Opis: Każdy programista powinien poświęcić 10 godzin na dogłębne poznanie swojego zintegrowanego środowiska pracy, aby móc z niego efektywnie (i efektownie) korzystać! A Ty ile czasu na to poświęciłeś? Warsztat jest przeznaczony dla programistów Java, korzystających z IntelliJ Idea, lub chcących się go nauczyć. Warsztat będzie miał formę Coding Dojo, podczas którego będziemy wspólnie pisać Katę i wzajemnie uczyć się korzystania z Idei bez użycia myszki. Warsztat będzie prowadzony po polsku, względnie może być po niemiecku;) Własny komputer nie jest wymagany, gdyż będziemy kodować wspólnie na jednym, podpiętym do rzutnika. Przyda się za to notatnik i długopis do zapisywania nowopoznanych kombinacji klawiszowych.

Na pomysł tego warsztatu wpadłem po tym, jak go z wielkim sukcesem przeprowadziłem w ostatnim projekcie. Po prostu, gdy udało się kupić IntelliJ Idea dla całego zespołu (o co bardzo ciężko walczyłem - skutecznie), musiałem wdrożyć kolegów w nowe środowisko. Wcześniej pokazywałem jedynie czym się różni Idea od Eclipse'a, ale to nie to samo co praktyka przy klawiaturze. Nie chciałem również słyszeć narzekań, że teraz trzeba się na nowo uczyć wszystkich kombinacji klawiszowych.

Zebrałem więc cały zespół, wyjaśniłem zasady i poszłooo! Było bardzo intensywnie, śmiesznie i co najważniejsze pouczająco. Ludzie wychodzili wówczas z sali z ugotowaną głową, ale widziałem później, że te warsztaty bardzo im pomogły. Zebrałem również bardzo pozytywne opinie na retrospektywie.

Mam nadzieję, że na Warsjawie będzie równie gorąco.

P.S. W razie jak byście chcieli się wcześniej zapisać na warsztaty, to przeczytajcie ten status.

poniedziałek, 1 września 2014

Implementacja Singleton’a w Javie

Ostatnio, podczas z jednej z rozmów rekrutacyjnych, dostałem pytanie, "A jak by Pan zaimplementował singleton w Javie?". Pytanie dość standardowe, mógł by je zadać każdy. Odpowiadam więc: „Klasa, z prywatnym konstruktorem, z polem statycznym o typie zadeklarowanej klasy, metoda getInstnce(), itd.”. Rekruter na to: "No dobra, a jakiś inny pomysł?".

Na szybko nie przychodziło mi jednak nic do głowy... Wtedy padło pytanie, które zmotywowało mnie do przygotowania tego wpisu: "A czytał Pan Effective Java, Joshua Bloch?". A no nie czytałem i nie sądzę, abym ją przeczytał.

Dlaczego?

Przede wszystkim uważam że ta książka jest trochę przestarzałą. Drugie wydanie pochodzi z 2008 roku i informacje w niej zawarte są trochę nieaktualne. To nie książka o wzorcach projektowych Bandy Czworga, która nie traci na swojej aktualności, a jedynie pozycja o tym jak coś tam dobrze zrobić w Javie. I tak przykładowo rozdział: "Item 51 Beware the performance of string concatenation", traktujące o tym, aby lepiej używać StringBuilder’a niż + do sklejania tekstów, jest już dawno nieaktualne! Chciałem kiedyś pisać posta o tym, ale na stackoverflow i jeszcze gdzieś tam już dawno o tym było. Nie wiem tylko od kiedy dokładnie istnieje ten mechanizm zamiany + na StringBuilder’a w Javie.

O innych dobrych praktykach, można się dowiedzieć zawsze z innych źródeł, niekoniecznie czytając wspomnianą książkę.

Dobra wróćmy do tematu wpisu. W innym rozdziale Effective Java (Item 3: Enforce the singleton property with a private constructor or an enum type), jest zalecenie, aby Singletona implementować za pomocą Enuma. Z tym rozwiązaniem spotkałem się po raz pierwszy podczas review kodu kogoś, kto czytał tę książkę. Użycie wówczas enuma w roli singletonu było dla mnie zupełnie niezrozumiałe! Musiałem dopytać autora o co chodzi.

Dlaczego nie lubię tego rozwiązania? Spójrzmy na przykładowy kawałek kodu (inspirowany Joshuą Blochem, co bym za dużo nie musiał wymyślać, jak tu mądrze użyć singletona). Kod jest i tak kiepski (obliczanie czasu), ale chodzi mi o zaprezentowanie działania omawianego wzorca.
public enum Elvis {
    INSTANCE;

    private final int ELVIS_BIRTHDAY_YEAR = 1935;

    public int howOldIsElvisNow() {
        return new GregorianCalendar().get(Calendar.YEAR) - ELVIS_BIRTHDAY_YEAR;
    }
}

public class ElvisProfitService {

    public double ELVIS_SALARY_YEAR = 70_000;

    public double calculateElvisProfit() {
        return Elvis.INSTANCE.howOldIsElvisNow() * ELVIS_SALARY_YEAR;
    }
}

No i weź tu panie przetestuj taki kod! Możemy jeszcze Elvisa statycznie zaimportować, to linijka 6 skróci się do jeszcze mniej czytelnej formy.

return INSTANCE.howOldIsElvisNow() * ELVIS_SALARY_YEAR;

Ktoś ma jakieś pomysły jak taki kod przetestować? Da się oczywiście, z wykorzystaniem PowerMock’a [link do rozwiązania na końcu ^1], ale chyba nie o to chodzi aby pisać nietestowany kod?

Dlaczego wolę starszą wersję tegoż rozwiązania:

public class Elvis {

    private static final Elvis INSTANCE = new Elvis();

    private final int ELVIS_BIRTHDAY_YEAR = 1935;

    private Elvis() {
    }

    public static Elvis getInstance() {
        return INSTANCE;
    }

    public int howOldIsElvisNow() {
        return new GregorianCalendar().get(Calendar.YEAR) - ELVIS_BIRTHDAY_YEAR;
    }
}

Dochodzi prywatny konstruktor, statyczna metoda getInstance() i inicjalizacja pola klasy wraz z deklaracją.

W tym przypadku kod korzystający z tego singletonu, mógłby być następujący:

public class ElvisProfitService {

    private final double ELVIS_SALARY_YEAR = 70_000;
    private Elvis elvis = Elvis.getInstance();

    public double calculateElvisProfit() {
        return elvis.howOldIsElvisNow() * ELVIS_SALARY_YEAR;
    }

    // For tests
    void setElvis(Elvis elvis) {
        this.elvis = elvis;
    }
}

W linii 4 wywołałem getInstance(), aby w przykładowym kodzie produkcyjnym było wszystko cacy. Dzięki temu, zależność ta jest definiowana jako pole w kasie i mamy setter do tego, więc możemy sobie bardzo ładnie przetestować tą funkcjonalność, bez hackowania z PowerMockiem:

public class ElvisProfitServiceTest {

    @Test
    public void shouldCalculateElvisProfit() {
        // given
        ElvisProfitService service = new ElvisProfitService();
        Elvis elvis = mock(Elvis.class);
        when(elvis.howOldIsElvisNow()).thenReturn(1);
        service.setElvis(elvis);

        // when
        double elvisProfit = service.calculateElvisProfit();

        // then
        assertEquals(70_000, elvisProfit, 0.1);
    }
}

W sekcji given mamy bardzo ładnie zdefiniowane zachowanie, za pomocą Mockito, jakie ma przyjmować masz singleton na potrzeby tego testu.

A Ty jak definiujesz (o ile to robisz) swoje singletony? Które rozwiązanie uważasz za lepsze?



[1] Co do rozwiązania zagadki, jak przetestować Singletona jako Enum’a, to tutaj jest odpowiednia rewizja na github’ie: SingletonInJava e714fb a kod poniżej:

@RunWith(PowerMockRunner.class)
@MockPolicy(ElvisMockPolicy.class)
public class ElvisProfitServiceTest {

    @Test
    public void shouldCalculateElvisProfit() {
        // given
        ElvisProfitService service = new ElvisProfitService();

        // when
        double elvisProfit = service.calculateElvisProfit();

        // then
        assertEquals(70_000, elvisProfit, 0.1);
    }
}

public class ElvisMockPolicy implements PowerMockPolicy {

    @Override
    public void applyClassLoadingPolicy(MockPolicyClassLoadingSettings settings) {
        settings.addFullyQualifiedNamesOfClassesToLoadByMockClassloader("com.blogspot.mstachniuk.singletoninjava.Elvis");
    }

    @Override
    public void applyInterceptionPolicy(MockPolicyInterceptionSettings settings) {
        Method method = Whitebox.getMethod(Elvis.class, "howOldIsElvisNow");
        settings.proxyMethod(method, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return 1.0;
            }
        });
    }
}