16 października 2009
Java Developers' Day 2009 moimi oczami
Ten postał został przeniesiony na mojego nowego bloga i można go znaleźć tutaj.
Etykiety:
Java Developers' Day,
konferencje
26 września 2009
Jak odmienić sposób programowania używając refaktoryzacji - moje wrażenia
Ten postał został przeniesiony na mojego nowego bloga i można go znaleźć tutaj.
Etykiety:
książki,
refaktoryzacja
6 sierpnia 2009
Efektywny programista Java, część 3 i 4 - klasy użytkowe i unikanie zbędnego powielania obiektów
Dzisiaj kolejna porcja porad jak efektywnie programować w Javie. Tym razem w jednym poście dwie porady, bo każda z nich jest zbyt krótka, by umieszczać je oddzielnie.
Składa się ona z kilku/kilkunastu metod statycznych używanych w różnych miejscach aplikacji. Taka klasa nie powinna umożliwiać tworzenia swojej instancji, gdyż jest to zbędne.
Bardzo łatwo możemy wymusić takie zachowanie na innych programistach tworząc konstruktor prywatny:
Dzięki takiemu prostemu zabiegowi, nasz kod zyskał na czytelności, a inni programiście nie będą używać naszej klasy w sposób niepoprawny.
Sprawdzamy tutaj, czy czyjaś data urodzin jest wcześniejsza niż moja. Tworzymy obiekt klasy Calendar, ustawiamy mu odpowiednie wartości roku, miesiąca i dnia, a następnie porównujemy ze zmienną birthDate.
Gdy wywołamy metodę kolejny raz, obiekt calendar zostanie utworzony ponownie i zostanie mu ustawiona ta sama data co poprzednio. Nie jest to rozwiązanie najbardziej optymalne. Widać tutaj wyraźnie, że tworzenie obiektu calendar i ustawianie mu odpowiedniej wartości powinno zostać wydzielone poza metodę i wykonywane tylko raz. Efekt taki możemy uzyskać przenosząc fragment kodu do bloku statycznego, a zmienną klasy Date uczynić prywatną i statyczną:
Teraz nasza metoda będzie wykonywała się trochę szybciej. Oczywiście zysk będzie znacznie większy, gdy taki wielokrotnie używany obiekt będzie bardziej skomplikowany, a jego tworzenie kosztowniejsze i bardziej czasochłonne.
Klasy użytkowe
Prawie w każdym projekcie pojawia się przynajmniej jedna klasa, która gromadzi metody użytkowe wspomagające działanie aplikacji. Taką klasę nazywamy najczęściej klasą pomocniczą (ang. utility class).Składa się ona z kilku/kilkunastu metod statycznych używanych w różnych miejscach aplikacji. Taka klasa nie powinna umożliwiać tworzenia swojej instancji, gdyż jest to zbędne.
Bardzo łatwo możemy wymusić takie zachowanie na innych programistach tworząc konstruktor prywatny:
public class Utils {
/*
* This is utility class, you don't have to create instance to use it
*/
private Utils() { }
public static String prepareUserStringForEmail(User user) {
// ...
}
public static String createRandomString(int length) {
// ...
}
public static String formatDateWithTime(Date date) {
// ...
}
}
Dzięki takiemu prostemu zabiegowi, nasz kod zyskał na czytelności, a inni programiście nie będą używać naszej klasy w sposób niepoprawny.
Optymalizowanie tworzenia obiektów, których używamy wielokrotnie
Przyjrzyjmy się poniższemu fragmentowi pewnej klasy:
public class Utils {
/*
* This is utility class, you don't have to create instance to use it
*/
private Utils() { }
public static boolean isOlderThanCodeHardGoProBlogOwner(Date birthDate) {
if(birthDate == null) {
throw new IllegalArgumentException("Date can not be null");
}
Calendar calendar = Calendar.getInstance();
calendar.set(1984, Calendar.JULY, 22);
Date codeHardGoProOwnerDateOfBirth = calendar.getTime();
return birthDate.compareTo(codeHardGoProOwnerDateOfBirth) < 0;
}
}
Sprawdzamy tutaj, czy czyjaś data urodzin jest wcześniejsza niż moja. Tworzymy obiekt klasy Calendar, ustawiamy mu odpowiednie wartości roku, miesiąca i dnia, a następnie porównujemy ze zmienną birthDate.
Gdy wywołamy metodę kolejny raz, obiekt calendar zostanie utworzony ponownie i zostanie mu ustawiona ta sama data co poprzednio. Nie jest to rozwiązanie najbardziej optymalne. Widać tutaj wyraźnie, że tworzenie obiektu calendar i ustawianie mu odpowiedniej wartości powinno zostać wydzielone poza metodę i wykonywane tylko raz. Efekt taki możemy uzyskać przenosząc fragment kodu do bloku statycznego, a zmienną klasy Date uczynić prywatną i statyczną:
public class Utils {
private final static Date CODE_HARD_GO_PRO_BLOG_OWNER_BIRTH_DATE;
static {
Calendar calendar = Calendar.getInstance();
calendar.set(1984, Calendar.JULY, 22);
CODE_HARD_GO_PRO_BLOG_OWNER_BIRTH_DATE = calendar.getTime();
}
private Utils() { }
public static boolean isOlderThanCodeHardGoProBlogOwner(Date birthDate) {
if(birthDate == null) {
throw new IllegalArgumentException("Date can not be null");
}
return birthDate.compareTo(CODE_HARD_GO_PRO_BLOG_OWNER_BIRTH_DATE) < 0;
}
}
Teraz nasza metoda będzie wykonywała się trochę szybciej. Oczywiście zysk będzie znacznie większy, gdy taki wielokrotnie używany obiekt będzie bardziej skomplikowany, a jego tworzenie kosztowniejsze i bardziej czasochłonne.
Etykiety:
efektywny programista,
how-to,
java
31 lipca 2009
Wicket - się dzieje
Ostatnio społeczność związana z frameworkiem Wicket ma kilka powodów do zadowolenia. Po pierwsze pojawiła się finalna wersja 1.4. Najważniejsza zmiana w porównaniu z wersją 1.3 to całkowite przejście na Javę 1.5 i wprowadzenie generycznego interfejsu IModel wraz z implementacjami. O wszystkich nowościach i zmianach można poczytać tutaj.
Jednocześnie z pojawieniem się wersji 1.4 został opublikowany ostatni upgrade wersji 1.3 o numerze 1.3.7 poprawiający kilkanaście "bugów". Autorzy zapowiadają, że jeśli nie pojawią się krytyczne błędy to ta gałąź nie będzie dalej rozwijana. W związku z tym należy się powoli przygotowywać do migracji na wersję 1.4 w aplikacjach używających Wicketa 1.3.x. Problem dotyczy również i mnie, bo moja magisterka używa wersji 1.3.6.
Kolejnym wydarzeniem istotnym dla fanów Wicketa jest opublikowanie w serwisie RefCardz ściągawki (ang. cheatsheet) o tym frameworku. Na kilku stronach zebrano najważniejsze informacje, najlepsze praktyki i spor porad bardzo przydatnych dla osób używających Wicketa. Całość można pobrać tutaj.
I na koniec informacja bardziej z naszego, polskiego poletka. Paweł Szulc pracuje nad mavenowym archetypem znacznie przyśpieszającym rozpoczęcie pracy z Wicketem. Projekt nazywa się WicketCool i można się z nim zapoznać pod tym adresem. Bardzo podoba mi się pomysł stworzenia czegoś takiego i mam nadzieję, że pomysł zyska na popularności, a Pawłowi należą się podziękowania za poświęcony czas i po prostu za dobrą robotę.
Dodam tylko, że sam projekt miał premierę na prezentacji Pawła podczas tegorocznej Javarsovii.
Jednocześnie z pojawieniem się wersji 1.4 został opublikowany ostatni upgrade wersji 1.3 o numerze 1.3.7 poprawiający kilkanaście "bugów". Autorzy zapowiadają, że jeśli nie pojawią się krytyczne błędy to ta gałąź nie będzie dalej rozwijana. W związku z tym należy się powoli przygotowywać do migracji na wersję 1.4 w aplikacjach używających Wicketa 1.3.x. Problem dotyczy również i mnie, bo moja magisterka używa wersji 1.3.6.
Kolejnym wydarzeniem istotnym dla fanów Wicketa jest opublikowanie w serwisie RefCardz ściągawki (ang. cheatsheet) o tym frameworku. Na kilku stronach zebrano najważniejsze informacje, najlepsze praktyki i spor porad bardzo przydatnych dla osób używających Wicketa. Całość można pobrać tutaj.
I na koniec informacja bardziej z naszego, polskiego poletka. Paweł Szulc pracuje nad mavenowym archetypem znacznie przyśpieszającym rozpoczęcie pracy z Wicketem. Projekt nazywa się WicketCool i można się z nim zapoznać pod tym adresem. Bardzo podoba mi się pomysł stworzenia czegoś takiego i mam nadzieję, że pomysł zyska na popularności, a Pawłowi należą się podziękowania za poświęcony czas i po prostu za dobrą robotę.
Dodam tylko, że sam projekt miał premierę na prezentacji Pawła podczas tegorocznej Javarsovii.
30 lipca 2009
Efektywny programista Java, część 2 - łatwiejsze tworzenie parametryzowanych kolekcji i obiektów
Tym razem spróbujemy ułatwić sobie tworzenie parametryzowanych typów kolekcji i obiektów. Pierwsza myśl jaka nam przychodzi do głowy to po prostu użycie konstruktora:
To jeszcze nie są zbyt skomplikowane przykłady, ale jeśli okaże się, że musimy stworzyć Mapę złożoną z obiektu i innej kolekcji:
to pojawia się spora ilość zdublowanego kodu z informacją o typach parametrów po lewej i prawej stronie deklaracji.
Okazuje się, że można tego uniknąć wykorzystując tzw. "wnioskowanie typów". Kompilator będzie wiedział jaki tym parametryzowanej instancji ma zwrócić na podstawie tego, do jakiej zmiennej będziemy chcieli zwracany obiekt przypisać. Wygodnym sposobem jest zebranie wszystkich takich metod w jednej klasie użytkowej:
Teraz możemy zobaczyć o ile krótszy i wygodniejszy jest kod stosujący wnioskowanie typów:
Możemy skorzystać z wnioskowania typów również przy tworzeniu parametryzowanych obiektów innych niż kolekcje, ale tutaj zaleta jego użycia jest widoczna najbardziej.
// ...
List<User> usersList = new ArrayList<User>();
Map<IpAddress, User> ipUsersMap = new HashMap<IpAddress, User>();
// ...
To jeszcze nie są zbyt skomplikowane przykłady, ale jeśli okaże się, że musimy stworzyć Mapę złożoną z obiektu i innej kolekcji:
// ...
Map<IpAddress, List<User>> ipUserMap = new HashMap<IpAddress, List<User>>();
// ...
to pojawia się spora ilość zdublowanego kodu z informacją o typach parametrów po lewej i prawej stronie deklaracji.
Okazuje się, że można tego uniknąć wykorzystując tzw. "wnioskowanie typów". Kompilator będzie wiedział jaki tym parametryzowanej instancji ma zwrócić na podstawie tego, do jakiej zmiennej będziemy chcieli zwracany obiekt przypisać. Wygodnym sposobem jest zebranie wszystkich takich metod w jednej klasie użytkowej:
package pl.tdziurko.effectivejava
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
/**
*
* @author Tomasz Dziurko
*/
public class Helper {
// Do not instantiate this class, this is utility class
private Helper() { }
public static <E> ArrayList<E> newArrayList() {
return new ArrayList<E>();
}
public static <E,K> HashMap <E,K> newHashMap() {
return new HashMap<E,K>();
}
public static <E> HashSet <E> newHashSet() {
return new HashSet<E>();
}
}
Teraz możemy zobaczyć o ile krótszy i wygodniejszy jest kod stosujący wnioskowanie typów:
// ...
List<User> usersList = new ArrayList<User>();
List<User> usersList2 = Helper.newArrayList();
Map<IpAddress, User> ipUsersMap = new HashMap<IpAddress, User>();
Map<IpAddress, User> ipUsersMap2 = Helper.newHashMap();
Map<IpAddress, List<User>> ipUserMap = new HashMap<IpAddress, List<User>>();
Map<IpAddress, List<User>> ipUserMap2 = Helper.newHashMap();
// ...
Możemy skorzystać z wnioskowania typów również przy tworzeniu parametryzowanych obiektów innych niż kolekcje, ale tutaj zaleta jego użycia jest widoczna najbardziej.
Etykiety:
efektywny programista,
how-to,
java
Efektywny programista Java, część 1 - singletony
Zgodnie z zapowiedzią w poprzednim poście, dzisiaj początek cyklu postów z najciekawszymi poradami z książki "Java. Efektywne programowanie". W pierwszej kolejności postaram się przedstawić te tematy, z którymi programista Java może zetknąć się najczęściej.
Najczęściej singleton w Javie wygląda następująco:
W powyższym przykładzie widać od razu, że jest to singleton: prywatny konstruktor i statyczne pole finalne z jedyną instancją klasy dają o tym wystarczająco jasny sygnał.
Drugi sposób przedstawiony w książce jest bardzo podobny:
Stosując powyższe podejście mamy większą elastyczność przy późniejszych modyfikacjach naszej klasy. Możemy bez problemu (czyli bez widocznych zmian w zewnętrznym wyglądzie klasy) zmienić implementację metody getInstance(), tak aby zwracała nie jedyną instancję Zbigniewa Bońka, ale na przykład jedną instancję dla danego wątku czy danego klienta.
Oba podejścia nie są niestety odporne na refleksję, nie są również przystosowane do serializacji. Jeśli chcemy, aby nasz singleton po serializacji i deserializacji był ciągle singletonem poza dodaniem implements Serializable musimy przeładować metodę readResolve() tak, aby zwracała obiekt INSTANCE.
Z kolei przed refleksją można się uchronić dodając blok w konstruktorze, który rzuca wyjątek w momencie, gdy istnieje już instancja obiektu tej klasy.
Ostatnim (i najbardziej polecanym przez autora książki) sposobem na tworzenie singletonu jest zastosowanie typu wyliczeniowego:
Dzięki zastosowaniu typu wyliczeniowego mamy za jednym zamachem załatwiony problem singletonu, bezpieczeństwa serializacji i zabezpieczenie przed użyciem refleksji. Wszystko zapewnia sam język i nie musimy się o to martwić.
Osobiście najczęściej stosowałem podejście z polem private final static i metodą getInstance(), ale myślę, że zastosowanie typu wyliczeniowego jest bardzo interesującą alternatywą, którą warto dodać do swojego repertuaru :)
Trzy sposoby na tworzenie singletonów
Najczęściej singleton w Javie wygląda następująco:
package pl.tdziurko.effectivejava;
public class Boniek {
public static final Boniek INSTANCE = new Boniek();
private Boniek() {
// stwórz jedyną instancję Zbigniewa Bońka
}
public void doMagicWithBall() {
// dokonaj czegoś niesamowitego na boisku
}
}
W powyższym przykładzie widać od razu, że jest to singleton: prywatny konstruktor i statyczne pole finalne z jedyną instancją klasy dają o tym wystarczająco jasny sygnał.
Drugi sposób przedstawiony w książce jest bardzo podobny:
public class Boniek {
private static final Boniek INSTANCE = new Boniek();
private Boniek() {
// stwórz jedyną instancję Zbigniewa Bońka
}
public Boniek getInstance() {
return INSTANCE;
}
public void doMagicWithBall() {
// dokonaj czegoś niesamowitego na boisku
}
}
Stosując powyższe podejście mamy większą elastyczność przy późniejszych modyfikacjach naszej klasy. Możemy bez problemu (czyli bez widocznych zmian w zewnętrznym wyglądzie klasy) zmienić implementację metody getInstance(), tak aby zwracała nie jedyną instancję Zbigniewa Bońka, ale na przykład jedną instancję dla danego wątku czy danego klienta.
Oba podejścia nie są niestety odporne na refleksję, nie są również przystosowane do serializacji. Jeśli chcemy, aby nasz singleton po serializacji i deserializacji był ciągle singletonem poza dodaniem implements Serializable musimy przeładować metodę readResolve() tak, aby zwracała obiekt INSTANCE.
Z kolei przed refleksją można się uchronić dodając blok w konstruktorze, który rzuca wyjątek w momencie, gdy istnieje już instancja obiektu tej klasy.
Ostatnim (i najbardziej polecanym przez autora książki) sposobem na tworzenie singletonu jest zastosowanie typu wyliczeniowego:
public enum Boniek {
INSTANCE;
void doMagicWithBall() {
// dokonaj czegoś niesamowitego na boisku
}
}
Dzięki zastosowaniu typu wyliczeniowego mamy za jednym zamachem załatwiony problem singletonu, bezpieczeństwa serializacji i zabezpieczenie przed użyciem refleksji. Wszystko zapewnia sam język i nie musimy się o to martwić.
Osobiście najczęściej stosowałem podejście z polem private final static i metodą getInstance(), ale myślę, że zastosowanie typu wyliczeniowego jest bardzo interesującą alternatywą, którą warto dodać do swojego repertuaru :)
Etykiety:
efektywny programista,
how-to,
java
28 lipca 2009
Dobiega końca pierwszy (najtańszy) etap rejestracji na Java Developers' Day 2009
Jeszcze tylko kilka dni mają wszyscy, którzy chcą się załapać w pierwszym (najbardziej promocyjnym) etapie rejestracji na konferencję Java Developers' Day 2009 w Krakowie, która odbędzie się 16 października 2009.
Do 31 lipca studenci mogą zaopatrzyć się w wejściówkę już za 167zł, co za całodniową, anglojęzyczną konferencję o Javie jest kwotą bardzo, ale to bardzo małą. Programiści "starsi wiekiem" ;) zapłacą za bilet 219 zł. Im bliżej października tym cena będzie rosła, więc jeśli ktoś wie, że na pewno chcę się wybrać do grodu Kraka posłuchać o Javie, to warto zapłacić już teraz. Oferta last minute dla spóźnialskich to wydatek prawie 600 złotych (swoją drogą last minute kojarzyło mi się zawsze z okazjami, no ale widocznie coś się ostatnio w tej kwestii pozmieniało :))
Niestety agenda nie jest jeszcze gotowa, ale po przejrzeniu relacji z poprzednich edycji mam nadzieję, że tegoroczne JDD nie będzie gorsze.
PS: Sponsorem tego posta jest Dworzec Zachodni w Warszawie, firma PKP i jej spóźniony o ponad 60 minut pociąg.
Do 31 lipca studenci mogą zaopatrzyć się w wejściówkę już za 167zł, co za całodniową, anglojęzyczną konferencję o Javie jest kwotą bardzo, ale to bardzo małą. Programiści "starsi wiekiem" ;) zapłacą za bilet 219 zł. Im bliżej października tym cena będzie rosła, więc jeśli ktoś wie, że na pewno chcę się wybrać do grodu Kraka posłuchać o Javie, to warto zapłacić już teraz. Oferta last minute dla spóźnialskich to wydatek prawie 600 złotych (swoją drogą last minute kojarzyło mi się zawsze z okazjami, no ale widocznie coś się ostatnio w tej kwestii pozmieniało :))
Niestety agenda nie jest jeszcze gotowa, ale po przejrzeniu relacji z poprzednich edycji mam nadzieję, że tegoroczne JDD nie będzie gorsze.
PS: Sponsorem tego posta jest Dworzec Zachodni w Warszawie, firma PKP i jej spóźniony o ponad 60 minut pociąg.
Etykiety:
java,
konferencje
Subskrybuj:
Posty (Atom)