Re: [warszawa-jug] Pewien przypadek - przeciążanie byłoby zalecane?

76 views
Skip to first unread message

Michał Bartyzel

unread,
Jul 6, 2011, 4:04:52 PM7/6/11
to warsza...@googlegroups.com
Mo�esz poda� wi�cej kontekstu?

* Czy URL to twoja klasa, czy biblioteczna?

* Czy w ifach chodzi o to, �e item jest url'em w postaci obiektu URL
albo w postaci Stringa?

* Jakiej klasy/interfejsu jest item?

pozdr,
mb

W dniu 2011-07-06 21:59, Jacek Laskowski pisze:
> Cze��,
>
> W�a�nie trafi�em na poni�szy kawa�ek kodu i przyku� moj� uwag�, bo w
> zasadzie "zmusi�" mnie, aby go zamieni� na rozwi�zanie z metodami
> przeci��onymi.
>
> Ten kawa�ek kodu:
>
> if (item instanceof URL) {
> ...
> } else if (item instanceof String) {
> ...
> } else...
>
> zamieni�bym na:
>
> void doSth(URL url)
> void doSth(String url)
>
> Jakie s� wady/zalety mojej zmiany? S� �adniejsze rozwi�zania? Ch�tnie
> wys�ucha�bym bardziej obitych w projektach i moli ksi��kowych nt.
> projektowania.
>
> Jacek
>

Jacek Laskowski

unread,
Jul 6, 2011, 4:09:14 PM7/6/11
to warsza...@googlegroups.com
2011/7/6 Michał Bartyzel <mbartyz...@gmail.com>:

> * Czy URL to twoja klasa, czy biblioteczna?

Niech będzie java.net.URL, ale skoro padło pytanie, ciekawym
rozwiązania, gdyby tak nie było.

> * Czy w ifach chodzi o to, że item jest url'em w postaci obiektu URL albo w
> postaci Stringa?

Dokładnie tak.

> * Jakiej klasy/interfejsu jest item?

Założmy, że na wejściu dostajemy Object, ale chętnie wysłuchałbym, co
by było, gdyby realizował pewien interfejs, np. IUrl.

Jacek

--
Jacek Laskowski
Java EE, functional languages and IBM WebSphere - http://blog.japila.pl
Warszawa JUG conference = Confitura (formerly Javarsovia) :: http://confitura.pl

Piotr Zajączkowski

unread,
Jul 6, 2011, 4:19:33 PM7/6/11
to warsza...@googlegroups.com
A może rozwiązanie rodem z Confitury 2011 - chodzi mi o wzorzec
strategii przedstawiony bodajże przez Pawła Lipińskiego na prelekcji
dot. "re-fu*k-toryzacji" ?

Czyli masz klasę ItemHandler, która ma abstrakcyjną metodę
"handleItem(Object item)" i dziedziczące po niej URLItemHandler,
StringItemHandler, itp. Oraz kolekcję z obiektami tych klas, po której
iterujesz do czasu aż któryś z handlerów nie obsłuży item'a (załóżmy,
że metoda zwraca true, jeśli obsłużenie powiodło się).

> --
> Otrzymujesz tę wiadomość, ponieważ subskrybujesz grupę dyskusyjną Google o nazwie "Warszawa Java User Group (Warszawa JUG)".
>
> Aby zamieszczać posty w tej grupie, wyślij e-mail na adres warsza...@googlegroups.com.
> Aby anulować subskrypcję tej grupy, wyślij e-mail na adres warszawa-jug...@googlegroups.com.
> Aby uzyskać więcej informacji, odwiedź tę grupę pod adresem http://groups.google.com/group/warszawa-jug?hl=pl.
>
>

Michał Bartyzel

unread,
Jul 6, 2011, 4:21:50 PM7/6/11
to warsza...@googlegroups.com
Je�li zak�adamy, �e jest IUrl, kt�rego implementacje
opakowuj� URL oraz String, to kod z poszczeg�lnych if�w
ma ze sob� co� wsp�lnego.


if (item instanceof URL) {
...
} else if (item instanceof String) {
...
} else...


W takim przypadku proponujďż˝
1. Nazwaďż˝ to, co robi kod w ifach - np. 'przekieruj do tego adresu'
2. W IUrl wprowadziďż˝ metodďż˝ redirect()
3. Kod z if�w przenie�� do implementacji metody redirect() w
poszczeg�lnych implementacjach IUrl

Wtedy zamiast if�w + instanceof mamy: item.redirect()

pozdr,
mb

W dniu 2011-07-06 22:09, Jacek Laskowski pisze:
> 2011/7/6 Michaďż˝ Bartyzel<mbartyz...@gmail.com>:


>
>> * Czy URL to twoja klasa, czy biblioteczna?
>

> Niech b�dzie java.net.URL, ale skoro pad�o pytanie, ciekawym
> rozwi�zania, gdyby tak nie by�o.
>
>> * Czy w ifach chodzi o to, �e item jest url'em w postaci obiektu URL albo w
>> postaci Stringa?
>
> Dok�adnie tak.


>
>> * Jakiej klasy/interfejsu jest item?
>

> Za�o�my, �e na wej�ciu dostajemy Object, ale ch�tnie wys�ucha�bym, co
> by by�o, gdyby realizowa� pewien interfejs, np. IUrl.
>
> Jacek
>

Jacek Laskowski

unread,
Jul 6, 2011, 3:59:36 PM7/6/11
to Warszawa-JUG
Cześć,

Właśnie trafiłem na poniższy kawałek kodu i przykuł moją uwagę, bo w
zasadzie "zmusił" mnie, aby go zamienić na rozwiązanie z metodami
przeciążonymi.

Ten kawałek kodu:

if (item instanceof URL) {
...
} else if (item instanceof String) {
...
} else...

zamieniłbym na:

void doSth(URL url)
void doSth(String url)

Jakie są wady/zalety mojej zmiany? Są ładniejsze rozwiązania? Chętnie
wysłuchałbym bardziej obitych w projektach i moli książkowych nt.
projektowania.

Bartek Kuczyński

unread,
Jul 6, 2011, 4:47:53 PM7/6/11
to warsza...@googlegroups.com
Trochę podobna propozycja do tej Michała. Bez konieczności zmiany interfejsu.

Utworzyć sobie klasę, która udostępnia metodę redirect(Object), a w
środku ma różne prywatne odmiany dla różnych typów.

Swoją drogą można to machnąć jako scalowy object i nie ma później
problemu z tworzeniem obiektów. Jak musisz robić w pure javie to
wewnętrzna klasa prywatna.

Pozdrawiam
Bartek "Koziołek" Kuczyński
http://koziolekweb.pl
Lepiej pomyśleć dwa razy i zacząć programować
niż dwa razy programować i potem zacząć myśleć
 \     /
 ~00~
  \_/
   |||

W dniu 6 lipca 2011 22:21 użytkownik Michał Bartyzel
<mbartyz...@gmail.com> napisał:
> Jeśli zakładamy, że jest IUrl, którego implementacje
> opakowują URL oraz String, to kod z poszczególnych ifów
> ma ze sobą coś wspólnego.


>
>
> if (item instanceof URL) {
>  ...
> } else if (item instanceof String) {
>  ...
> } else...
>
>

> W takim przypadku proponuję
> 1. Nazwać to, co robi kod w ifach - np. 'przekieruj do tego adresu'
> 2. W IUrl wprowadzić metodę redirect()
> 3. Kod z ifów przenieść do implementacji metody redirect() w poszczególnych
> implementacjach IUrl
>
> Wtedy zamiast ifów + instanceof mamy: item.redirect()


>
>
>
> pozdr,
> mb
>
> W dniu 2011-07-06 22:09, Jacek Laskowski pisze:
>>

>> 2011/7/6 Michał Bartyzel<mbartyz...@gmail.com>:


>>
>>> * Czy URL to twoja klasa, czy biblioteczna?
>>

>> Niech będzie java.net.URL, ale skoro padło pytanie, ciekawym
>> rozwiązania, gdyby tak nie było.
>>

>>> * Czy w ifach chodzi o to, że item jest url'em w postaci obiektu URL albo
>>> w
>>> postaci Stringa?
>>
>> Dokładnie tak.


>>
>>> * Jakiej klasy/interfejsu jest item?
>>

>> Założmy, że na wejściu dostajemy Object, ale chętnie wysłuchałbym, co

>> by było, gdyby realizował pewien interfejs, np. IUrl.
>>
>> Jacek
>>
>

Irek Matysiewicz

unread,
Jul 6, 2011, 11:38:16 PM7/6/11
to warsza...@googlegroups.com
W dniu 2011-07-06 21:59, Jacek Laskowski pisze:
> Ten kawałek kodu:
>
> if (item instanceof URL) {
> ...
> } else if (item instanceof String) {
> ...
> } else...
>
> zamieniłbym na:
>
> void doSth(URL url)
> void doSth(String url)
Prawdoposobnie tutaj obie metody robią to samo, tylko jedna przyjmuje
URL-a jako URL, a druga jako String?
Wtedy ja by m po prostu dał jedną metodę:
void doSth(URL url)
Jak ktoś bardzo chce bawić się stringami to niech woła: doSth(new
URL(urlJakoString)). Ma to taką zaletę, że jak masz dziesięć takich
metod doSth(URL url), to nie musisz dla każdej z nich pisać dwóch
przeciążonych wersji i paskudzić sobie API ("It seems that perfection is
attained not when there is nothing more to add, but when there is
nothing more to remove").

Jeśli jednak z jakiegoś powodu potrzebna ta wersja ze Stringiem
zrobiłbym tak:
void doSth(String url) { doSth(new URL(url)) }

Jeśli te metody robią jednak coś zupełnie innego, to chyba lepiej dać im
różne nazwy dla jasności:
void zróbcoś(URL url)
void zróbcośInnego(String url)


A te wspomniane przez was rozwiązania z if(url instanceof ...) czy z
IUrl zostawiłbym dla bardziej skomplikowanych sytuacji, a ta tutaj chyba
taka nie jest. :-)

Jacek Laskowski

unread,
Jul 7, 2011, 4:18:20 AM7/7/11
to warsza...@googlegroups.com
2011/7/6 Piotr Zajączkowski <p.m.zaja...@gmail.com>:

> Czyli masz klasę ItemHandler, która ma abstrakcyjną metodę
> "handleItem(Object item)" i dziedziczące po niej URLItemHandler,
> StringItemHandler, itp. Oraz kolekcję z obiektami tych klas, po której
> iterujesz do czasu aż któryś z handlerów nie obsłuży item'a (załóżmy,
> że metoda zwraca true, jeśli obsłużenie powiodło się).

Dla niewielkiego zestawu możliwych przypadków, powiedzmy 2-4, mam
wrażenie, że to przerost formy nad treścią. Zupełnie nie pasuje mi to
podejście. W zasadzie, my oprogramowujemy coś (decyzja, czy możemy coś
wykonać), co zrobi za nas doskonale kompilator i JVM.

Jacek Laskowski

unread,
Jul 7, 2011, 4:19:51 AM7/7/11
to warsza...@googlegroups.com
2011/7/6 Michał Bartyzel <mbartyz...@gmail.com>:
> Jeśli zakładamy, że jest IUrl
...
> W takim przypadku proponuję
...

> Wtedy zamiast ifów + instanceof mamy: item.redirect()

To wybrnąłeś sprytnie. A co w sytuacji, kiedy nie są? To uważam za tą
trudniejszą sytuację, bo wspólny interfejs, to prościzna i nie trzeba
wielkiej wiedzy projektowej :) Oczekuję więcej od praktyków :P

Jacek Laskowski

unread,
Jul 7, 2011, 4:22:16 AM7/7/11
to warsza...@googlegroups.com
2011/7/6 Bartek Kuczyński <bjkuc...@gmail.com>:

> Utworzyć sobie klasę, która udostępnia metodę redirect(Object), a w
> środku ma różne prywatne odmiany dla różnych typów.

Czy nie prościej/ładniej wystawić redirect(IUrl), jeśli to ma
odpowiadać propozycji Michała?!

Jacek Laskowski

unread,
Jul 7, 2011, 4:24:57 AM7/7/11
to warsza...@googlegroups.com
2011/7/7 Irek Matysiewicz <iir...@gmail.com>:

> Prawdoposobnie tutaj obie metody robią to samo, tylko jedna przyjmuje URL-a
> jako URL, a druga jako String?
> Wtedy ja by m po prostu dał jedną metodę:
> void doSth(URL url)
> Jak ktoś bardzo chce bawić się stringami to niech woła: doSth(new
> URL(urlJakoString)). Ma to taką zaletę, że jak masz dziesięć takich metod
> doSth(URL url), to nie musisz dla każdej z nich pisać dwóch przeciążonych
> wersji i paskudzić sobie API ("It seems that perfection is attained not when
> there is nothing more to add, but when there is nothing more to remove").

To wciąż nie rozwiązuje głównego problemu, gdzie muszę sprawdzić typ
parametru, przez instanceof przykładowo, i wywołać odpowiednią metodę,
nieprawdaż? :) Wolałbym wycisnąć jak najwięcej z jvm (i wykorzystać
czas na inne dywagacje, które znowu zaoszczędzą mi trochę czasu, który
znowu poświęcę na dywagacje, itp. - innymi słowy - nigdy i tak nie
będę miał więcej wolnego czasu :))

Irek Matysiewicz

unread,
Jul 7, 2011, 4:38:52 AM7/7/11
to warsza...@googlegroups.com
W dniu 7 lipca 2011 10:24 użytkownik Jacek Laskowski <ja...@japila.pl> napisał:
2011/7/7 Irek Matysiewicz <iir...@gmail.com>:

> Prawdoposobnie tutaj obie metody robią to samo, tylko jedna przyjmuje URL-a
> jako URL, a druga jako String?
> Wtedy ja by m po prostu dał jedną metodę:
> void doSth(URL url)
> Jak ktoś bardzo chce bawić się stringami to niech woła: doSth(new
> URL(urlJakoString)). Ma to taką zaletę, że jak masz dziesięć takich metod
> doSth(URL url), to nie musisz dla każdej z nich pisać dwóch przeciążonych
> wersji i paskudzić sobie API ("It seems that perfection is attained not when
> there is nothing more to add, but when there is nothing more to remove").

To wciąż nie rozwiązuje głównego problemu, gdzie muszę sprawdzić typ
parametru, przez instanceof przykładowo, i wywołać odpowiednią metodę,
nieprawdaż? :) Wolałbym wycisnąć jak najwięcej z jvm (i wykorzystać
czas na inne dywagacje, które znowu zaoszczędzą mi trochę czasu, który
znowu poświęcę na dywagacje, itp. - innymi słowy - nigdy i tak nie
będę miał więcej wolnego czasu :))


Z JVM to i dużo wyciśniesz (zwłaszcza od Javy 7, która zawiera invokedynamic, które jest jakby przeciążaniem metod na drugach), ale z samego języka Java (nawet w wersji 7) to tu za wiele raczej nie zdziałasz: albo dwie przeciążone metody, albo jedna metoda z parametrem typu Object i instanceof, albo jedna metoda akceptująca jakąś wypasioną klasę (URL, IUrl czy cośtam). Jak na mnie każde z tych podejść jest tak samo dobre jak i niedobre. Które z tych podejść będzie najlepsze chyba będzie zależeć od tego jak programiści-użytkownicy twojego API przeważnie chcieliby wygodnie tego używać i co konkretnie robisz.

Bartek Kuczyński

unread,
Jul 7, 2011, 4:39:25 AM7/7/11
to warsza...@googlegroups.com
@Jacku zależy czy to co przekazujesz do obecnej metody możesz
modyfikować czy nie za bardzo.


Pozdrawiam
Bartek "Koziołek" Kuczyński
http://koziolekweb.pl
Lepiej pomyśleć dwa razy i zacząć programować
niż dwa razy programować i potem zacząć myśleć
 \     /
 ~00~
  \_/
   |||

Michal Margiel

unread,
Jul 7, 2011, 4:40:54 AM7/7/11
to warsza...@googlegroups.com


W dniu 7 lipca 2011 10:24 użytkownik Jacek Laskowski <ja...@japila.pl> napisał:
2011/7/7 Irek Matysiewicz <iir...@gmail.com>:

> Prawdoposobnie tutaj obie metody robią to samo, tylko jedna przyjmuje URL-a
> jako URL, a druga jako String?
> Wtedy ja by m po prostu dał jedną metodę:
> void doSth(URL url)
> Jak ktoś bardzo chce bawić się stringami to niech woła: doSth(new
> URL(urlJakoString)). Ma to taką zaletę, że jak masz dziesięć takich metod
> doSth(URL url), to nie musisz dla każdej z nich pisać dwóch przeciążonych
> wersji i paskudzić sobie API ("It seems that perfection is attained not when
> there is nothing more to add, but when there is nothing more to remove").

To wciąż nie rozwiązuje głównego problemu, gdzie muszę sprawdzić typ
parametru, przez instanceof przykładowo, i wywołać odpowiednią metodę,
nieprawdaż? :) Wolałbym wycisnąć jak najwięcej z jvm (i wykorzystać
czas na inne dywagacje, które znowu zaoszczędzą mi trochę czasu, który
znowu poświęcę na dywagacje, itp. - innymi słowy - nigdy i tak nie
będę miał więcej wolnego czasu :))

zainteresuj się wzorcem "strategia", o którym wspomniał Piotr.

Prosty przykład:

Map handlers = new HashMap().add(String.class, new StringHandler()).add(URL.class, new UrlHandler())

public int executeFor(Object value){
    return getHandlerFor(value).execute(value);
}

private Handler getHandlerFor(Object value){
    if (handers.doesNotcontain(value.getClass()))
        throw new RuntimeException("No handler for given class");
   return handlers.get(value.getClass());
}


To oczywiście pseudokod, więc proszę nie pisać, że się nie kompiluję.

Ale! zaznaczam, że ja jestem przeciwny wciskaniu strategii na siłę wszedzie gdzie widzimy "if/switch". W prostych przypadkach to moim zdaniem jest zwykły "overdesign".
Osobiście nie mam nic do instukcji warunkowych ani "instanceof", trzeba podchodzić do tematu pragmatycznie, a nie zaraz zapisywać się do kampnii "anty-if" [1]

--
Pozdrawiam/Best regards
Michał Margiel

http://www.confitura.pl (dawniej Javarsovia)
http://www.linkedin.com/in/MichalMargiel
http://www.margiel.eu

mproch Gazeta.pl

unread,
Jul 7, 2011, 4:51:19 AM7/7/11
to warsza...@googlegroups.com
A ja bym dał te przeciążone metody, albo tylko jedną (np. z URL) tak jak pisał Irek wcześniej.

metoda doSth(Object o), która działa tylko dla stringa i urla strasznie mi cuchnie...
Zaczynamy robić na siłę coś a'la dynamiczne typowanie, a chyba nie o to chodzi.
Nieszczęsny użytkownik biblioteki będzie musiał albo zajrzeć do (oczywiście aktualnej i kompletnej) dokumentacji albo grzebać w kodzie.

A strategie, dodatkowe interfejsy i co tam jeszcze wydają mi się 'lekkim' nadinżynierowaniem (skoro jest to dyskusja Jacka to nie wypada używać słów angielskich :P)

pozdrawiam,
maciek 

--

Michal Margiel

unread,
Jul 7, 2011, 5:01:54 AM7/7/11
to warsza...@googlegroups.com


W dniu 7 lipca 2011 10:51 użytkownik mproch Gazeta.pl <mpr...@gazeta.pl> napisał:

A strategie, dodatkowe interfejsy i co tam jeszcze wydają mi się 'lekkim' nadinżynierowaniem (skoro jest to dyskusja Jacka to nie wypada używać słów angielskich :P)

wszak, też tak napisałem. Imho do spraw trzeba podchodzić indywidualnie. Nawet miałem  ostrą dyskusję z Bruno Bossolą[1], gdy ten na swojej prezentacji, na GeeConie 2010, chciał wprowadzać strategię dla pary if-else.

Wojciech Erbetowski

unread,
Jul 7, 2011, 5:26:57 AM7/7/11
to warsza...@googlegroups.com
Jeśli to ma być potem jeszcze używane przez ludzi i czytelne i odporne na błędy itd to strategia zdaje się najlepsza w tym przypadku, choć myślę, że przekombinowana. Osobiście przeciążyłbym metody.

Ale jeśli Jacku chcesz z JVM coś gotowego wycisnąć i mieć możliwie mało kodu, to proszę:

doSthWithUrlInObject(Object url) {
    doSthWithURL(new URL(Object.toString());
}

Oczywiście jest to rozwiązanie godne skrypciku do zrobienia czegoś na szybko, a nie skomitowania do aplikacji, z której ktoś faktycznie korzysta. Działa dla Stringa i URLa (choć tu jest niepotrzebny nakład pracy). Wymienione jedynie w celach edukacyjnych :-)

Michal Margiel

unread,
Jul 7, 2011, 5:37:46 AM7/7/11
to warsza...@googlegroups.com


W dniu 7 lipca 2011 11:26 użytkownik Wojciech Erbetowski <wojc...@erbetowski.pl> napisał:
Jeśli to ma być potem jeszcze używane przez ludzi i czytelne i odporne na błędy itd to strategia zdaje się najlepsza w tym przypadku, choć myślę, że przekombinowana. 

jeśli będzue uzywane przez ludzi i czytelne?? 
szczerze mówiac to moim zdaniem 
if (COŚTAM)
   return X;
else
  return Y;

jest DUŻO czytelniejsze niż strategia,  która z natury jest porozwalana po kilku klasach. IMHO strategia jest dobrym wyborem, jeśli lista IFów jest bardzo długo, lub jeśli jesteśmy PEWNI, że w niedługim czasie będziemy musieli dołożyć kolejne warunki. 

ps. A odporność na błędy (do pewnego stopnia) zapewni nam siatka testów jednostkowych a nie wybrany wzorzec :)

Wojciech Erbetowski

unread,
Jul 7, 2011, 5:49:36 AM7/7/11
to warsza...@googlegroups.com
W dniu 7 lipca 2011 11:37 użytkownik Michal Margiel <michal....@gmail.com> napisał:

jeśli będzue uzywane przez ludzi i czytelne?? 
szczerze mówiac to moim zdaniem 
if (COŚTAM)
   return X;
else
  return Y;

jest DUŻO czytelniejsze niż strategia,  która z natury jest porozwalana po kilku klasach. IMHO strategia jest dobrym wyborem, jeśli lista IFów jest bardzo długo, lub jeśli jesteśmy PEWNI, że w niedługim czasie będziemy musieli dołożyć kolejne warunki. 


Z reguły strategii nie trzeba czytać całej, żeby zrozumieć, zamiast ifów masz

URL url = getURLConverter(object).prepareURL(object)

Jak dla mnie to jest czytelniejsze. Jeśli przez słabe nazewnictwo albo skomplikowaną dziedzinę muszę zajrzeć do tych metod - wtedy już pewnie nie, ale i ify nie będą już zwięzłe wtedy.



Jacek Laskowski

unread,
Jul 7, 2011, 5:53:44 AM7/7/11
to warsza...@googlegroups.com
2011/7/7 Michal Margiel <michal....@gmail.com>:

> zainteresuj się wzorcem "strategia", o którym wspomniał Piotr.
>
> Prosty przykład:
> Map handlers = new HashMap().add(String.class, new
> StringHandler()).add(URL.class, new UrlHandler())

Ja widzę to jak rozwiązanie z przeciążonymi metodami tyle tylko, że w
moim rozwiązaniu rolę wyznaczania obsługi danego typu zrzucam na barki
jvm. W Twoim rozwiązaniu zakładasz, że typ jest kluczem, a tak działa
właśnie Java z przeciążonymi czy przesłoniętymi metodami.

Uzupełniam moją wcześniejszą wypowiedź: "Od praktyków wymagam więcej"
myślenia niż gadania :)

Piotr Zajączkowski

unread,
Jul 7, 2011, 7:43:06 AM7/7/11
to warsza...@googlegroups.com
No Jacek napisał w swoim poście:

If (...) {
//...
} else
if (...) {
//...
} else
...

Co zasugerowało mi (ten wielokropek na końcu), że ifów będzie dużo.
Dlatego zaproponowałem strategię. Natomiast jeśli ma być ich 2-4 (jak
później sprecyzował), to rzeczywiście zależy od konkretnego przypadku.

Co do przykładów, gdzie zalecacie tworzenie URL'a na podstawie
String'a, to pamiętajcie, że konstruktor klasy URL rzuca wyjątkiem, a
my za bardzo nie wiemy, jak go obsłużyć. Zatem lepszym rozwiązaniem
byłoby już wymuszenie na użytkowniku przekazywania Stringa.

Kolejnym rozwiązaniem, które *być może* dałoby się zaadaptować jest
opakowanie tych Stringów i URLi i czego tam jeszcze w jedną klasę
(właną) i stworzenie jej różnych konstruktorów (z parametrem String,
URL, itp.) a następnie przekazywanie obiektu tej klasy jako argumentu
dla metody doSth(). Ale to da się zastosować tylko dla konkretnych
przypadków - wciąż nie wiemy, co ma robić metoda doSth() i czemu ważne
było rozróżnienie typów.

Kolejnym rozwiązaniem (przy użyciu Grooviego) byłoby dołożenie
metod(y) do klasy Object i przeciążenie ich w String, URL (i innych
wymaganych), które wykonywałyby to, co chcemy osiągnąć lub pozwalały
np. konwertować wszystko na jeden spójny format. Następnie obiekt w
takim formacie dałoby radę przekazać do metody doSth(). Chodzi mi o
coś takiego:

Object o = ... // to co przekazał user
FajnaKlasaWspolna tempArg = o.convertToFajnyFormat();
doSth(tempArg);

Ale to rozwiązanie jest moim zdaniem brzydkie i brudzące w kodzie. Ale
zawsze jakieś ;D hehe ;)

Pzdr.

W dniu 7 lipca 2011 11:37 użytkownik Michal Margiel
<michal....@gmail.com> napisał:

Michał Bartyzel

unread,
Jul 7, 2011, 1:23:19 PM7/7/11
to warsza...@googlegroups.com
W dniu 2011-07-07 10:19, Jacek Laskowski pisze:
> 2011/7/6 Michaďż˝ Bartyzel<mbartyz...@gmail.com>:
>> Je�li zak�adamy, �e jest IUrl
> ...
>> W takim przypadku proponujďż˝
> ...
>> Wtedy zamiast if�w + instanceof mamy: item.redirect()
>
> To wybrn��e� sprytnie. A co w sytuacji, kiedy nie s�? To uwa�am za t�
> trudniejsz� sytuacj�, bo wsp�lny interfejs, to pro�cizna i nie trzeba
> wielkiej wiedzy projektowej :) Oczekuj� wi�cej od praktyk�w :P

Od praktyk�w oczekujesz pewnie rozwi�zania problemu. Postawi�e� problem,
otrzyma�e� klika rozwi�za�. Ka�y, kto opodwiedzia� poda� za�o�enia, przy
kt�rych jego rozwi�zanie ma sens. Je�li nie jeste� zadowolny, to pewnie
nie szuka�e� rozwi�znia problemu, tylko ciekawej dyskusji :) Albo nie
do�� szczeg�owo opisa�e� problem, jego kontekst i jakiego konkretnie
efektu siďż˝ spodziewasz.

pozdr,
mb

Jacek Laskowski

unread,
Jul 7, 2011, 6:03:37 PM7/7/11
to warsza...@googlegroups.com
2011/7/7 Michał Bartyzel <mbartyz...@gmail.com>:

> Od praktyków oczekujesz pewnie rozwiązania problemu. Postawiłeś problem,
> otrzymałeś klika rozwiązań. Każy, kto opodwiedział podał założenia, przy
> których jego rozwiązanie ma sens. Jeśli nie jesteś zadowolny, to pewnie nie
> szukałeś rozwiąznia problemu, tylko ciekawej dyskusji :) Albo nie dość
> szczegółowo opisałeś problem, jego kontekst i jakiego konkretnie efektu się
> spodziewasz.

Większość z propozycji była w moim odczuciu odejściem od głównego
problemu, jakby jego zaowalowaniem. Mam kilka ifów i chciałbym
zniwelować je rozwiązaniami już dostępnymi w jvm, w języku, a nie
oprogramowywać je. Kiedykolwiek kontrowałem propozycję, podawałem
powody, dla których to robię. Ja znalazłem rozwiązanie i nie
zauważyłem, aby ktokolwiek je wyciął jako nieodpowiednie, więc
mniemam, że mam rozwiązanie, ale bez wiary w swoje umiejętności
programistyczne, a na pewno projektowe, prosiłem o kontrpropozycje. Te
kilka propozycji, które padły, faktycznie nie były w pelni dla mnie
zadowalające, ale mam już świadomość, że może nie ma rozwiązania
lepszego? Czuję się zaszczycony moim wnioskiem :)

Pawel Cesar Sanjuan Szklarz

unread,
Jul 7, 2011, 7:16:47 PM7/7/11
to warsza...@googlegroups.com
Czesc

Mysle, ze ocena dowolnego rozwiazania tez powinna brac pod uwage w jakim kierunku spodziewamy sie przyrost funkcjonalnosci/kodu wokol tych if-ow. Na pewno ktos inny bedzie dodawal przypadki, jak bedzie mu wygodnie dodac to zrobi i pojdzie dalej bez patrzenia. Wazne tez, zeby trudno bylo zrobic blad przy modyfikacji.

Pawel.

2011/7/8 Jacek Laskowski <ja...@japila.pl>

Jacek Laskowski

unread,
Jul 8, 2011, 3:23:57 AM7/8/11
to warsza...@googlegroups.com
2011/7/8 Pawel Cesar Sanjuan Szklarz <paw...@gmail.com>:

> Mysle, ze ocena dowolnego rozwiazania tez powinna brac pod uwage w jakim
> kierunku spodziewamy sie przyrost funkcjonalnosci/kodu wokol tych if-ow.

Właśnie tu mam pewien problem, bo po tej dyskusji skłaniam się ku
podejściu, aby w ogóle zaniechać ifów. Chyba mnie pokręciło :)

Michal Margiel

unread,
Jul 8, 2011, 3:53:52 AM7/8/11
to warsza...@googlegroups.com
W dniu 8 lipca 2011 01:16 użytkownik Pawel Cesar Sanjuan Szklarz <paw...@gmail.com> napisał:
Czesc

Mysle, ze ocena dowolnego rozwiazania tez powinna brac pod uwage w jakim kierunku spodziewamy sie przyrost funkcjonalnosci/kodu wokol tych if-ow.

Ale tego często nie wiesz, czy będą wymagane zmiany. Mi się wydaję, że należy tu się kierować zasadą XP- YAGNI [1]. Pewnie każdy z nas (ja na pewno) widział  wielki "generyczny kod", bo "może kiedyś coś się zmieni, to będziemy na to gotowi". 
Problem tylko taki, że w wielu przypadkach to "kiedyś" nigdy nie następuje, a przekombinowany kod zostaje na zawsze...
 
Na pewno ktos inny bedzie dodawal przypadki, jak bedzie mu wygodnie dodac to zrobi i pojdzie dalej bez patrzenia. Wazne tez, zeby trudno bylo zrobic blad przy modyfikacji.

Tak jak napisałem wyżej, nie zawsze  "na pewno ktoś będzie dodawał". a jak już będzie to nie zapominajmy o pierwszej dyrektywie [2], i weźmy pod uwage to, że inni w naszym zespole też sa dobrymi programistami (a jeśli nie to zrobimy ich takimi siedząc z  nimi w parze ;))

--  

Irek Matysiewicz

unread,
Jul 8, 2011, 4:17:12 AM7/8/11
to warsza...@googlegroups.com
W końcu w programowaniu wszystko się sprowadza do:
- zadowolenia twojego i twojego klienta
- pieniędzy

Przeciążanie, if, strategia, invokedynamic, instanceof i tym podobne to tylko narzędzia: jak dobrze użyte mogą bardzo pomóc, ale nawet jak źle użyte to to wcale nie gwarantuje porażki. W wielu projektach jest g... w kodzie, a mimo to firmy na nich zarabiają niezłe pieniądze (np. jądro Linuksa czy Lombok którego kiedyś zjechaliśmy - nikt nad ich kodem za bardzo nie panuje, ale i tak mają się świetnie). Dobrze jest mieć swój styl (i ja i parę osób napisało jak oni by to zrobili), ale jak będziemy za głęboko w to wchodzić taka dyskusja staje się czysto akademicka nie wnosząca nic nowego, bo niemal każdy problem można dobrze rozwiązać na wiele sposobów.


Michal Margiel

unread,
Jul 8, 2011, 4:35:15 AM7/8/11
to warsza...@googlegroups.com


W dniu 8 lipca 2011 10:17 użytkownik Irek Matysiewicz <iir...@gmail.com> napisał:
ale jak będziemy za głęboko w to wchodzić taka dyskusja staje się czysto akademicka nie wnosząca nic nowego, bo niemal każdy problem można dobrze rozwiązać na wiele sposobów.


Zdrowy rozsądek nie powinien być zagłuszony przez jakikolwiek wzorzec projektowy. A niestety czasami tak bywa.

Adam Lider

unread,
Jul 8, 2011, 4:36:39 AM7/8/11
to warsza...@googlegroups.com
Witam, 
to i ja dorzuce sowje 5 groszy. Generalnie podejscie Michala do tego problemu wydaje mi sie najodpowiedniejsze. Dodam tylko, ze poza zlozonoscia logiki, wplyw moze miec tez jej poziom abstrakcji (z gory przepraszam za te gornolotne frazesy). Blizej mi do strategii, gdy mam wyrazic w kodzie warunki z domeny, a ify wydaja sie odpowiedniejsze gdy grzebiemy na dosc niskim poziomie. Ale oczywiscie liczy sie kontekst.

Swoja droga spojrzcie prosze na ten kod dosc prostego algorytmu:

public class BinarySearch {
    public static void main(String[] args) {
        int[] whitelist = In.readInts(args[0]);
        Arrays.sort(whitelist);
        while (!StdIn.isEmpty()) {
            int key = StdIn.readInt();
            if (rank(key, whitelist) == -1)
                StdOut.println(key);
           }
    }
    public static int rank(int key, int[] a) {
        int lo = 0;
        int hi = a.length - 1;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if      (key < a[mid]) hi = mid - 1;
            else if (key > a[mid]) lo = mid + 1;
            else return mid;
         }
         return -1;
    }    
}

Oczywiscie problem troszke inny, no i logika tutaj jest skonczona wiec ify sa oczywiste, chodzi mi bardziej o czytelnosc kodu, szczegolnie ifow. Pytanie jest czy ponizszy kod jest czytelny i pokusilibyscie sie o refaktoring tego kodu - metody rank(szczegolnie ify), aby zrobic ten kod "bardziej czytelny"? Formatowanie ifow nieprzypadkowe.

Pozdrawiam, Adam.

Jacek Laskowski

unread,
Jul 8, 2011, 6:03:29 AM7/8/11
to warsza...@googlegroups.com
2011/7/8 Michal Margiel <michal....@gmail.com>:

> Ale tego często nie wiesz, czy będą wymagane zmiany.

...


> weźmy pod uwage to, że inni w naszym zespole też sa dobrymi programistami (a jeśli nie to
> zrobimy ich takimi siedząc z  nimi w parze ;))

Gdybym nie przeczytał kto to napisał, nigdy, ale to nigdy nie
powiedziałbym, że to nasz MM :)

Jacek Laskowski

unread,
Jul 8, 2011, 6:07:47 AM7/8/11
to warsza...@googlegroups.com
2011/7/8 Adam Lider <adam....@googlemail.com>:

> Pytanie jest czy ponizszy kod jest czytelny i pokusilibyscie sie o
> refaktoring tego kodu - metody rank(szczegolnie ify), aby zrobic ten kod
> "bardziej czytelny"?

Dla mnie jest wystarczająco czytelny i nic bym nie zmienił, poza
wprowadzeniem stałej dla -1, która niewprawne oka (moje wliczając)
przykuwa swoją tajemniczością i lekko irytuje :)

Michal Margiel

unread,
Jul 8, 2011, 6:43:50 AM7/8/11
to warsza...@googlegroups.com


W dniu 8 lipca 2011 12:03 użytkownik Jacek Laskowski <ja...@japila.pl> napisał:
2011/7/8 Michal Margiel <michal....@gmail.com>:

> Ale tego często nie wiesz, czy będą wymagane zmiany.
...
> weźmy pod uwage to, że inni w naszym zespole też sa dobrymi programistami (a jeśli nie to
> zrobimy ich takimi siedząc z  nimi w parze ;))

Gdybym nie przeczytał kto to napisał, nigdy, ale to nigdy nie
powiedziałbym, że to nasz MM :)

Czasami mam wrażenie, że twój wiek zrobił już swoje :P

mproch Gazeta.pl

unread,
Jul 8, 2011, 6:45:54 AM7/8/11
to warsza...@googlegroups.com
W dniu 8 lipca 2011 12:07 użytkownik Jacek Laskowski <ja...@japila.pl> napisał:
2011/7/8 Adam Lider <adam....@googlemail.com>:

> Pytanie jest czy ponizszy kod jest czytelny i pokusilibyscie sie o
> refaktoring tego kodu - metody rank(szczegolnie ify), aby zrobic ten kod
> "bardziej czytelny"?

Dla mnie jest wystarczająco czytelny i nic bym nie zmienił, poza
wprowadzeniem stałej dla -1, która niewprawne oka (moje wliczając)
przykuwa swoją tajemniczością i lekko irytuje :)

Ja też bym się skłaniał do tego że jest wystarczająco czytelny - na warunki brzegowe nie ma mocnych ;)

Jedyny IMHO sposób żeby istotnie poprawić czytelność to użyć
Arrays.binarySearch :P
(chociaż zwraca różne ujemne liczby jak nie znajdzie elementu)
 
pozdrawiam,
maciek

Jacek

--
Jacek Laskowski
Java EE, functional languages and IBM WebSphere - http://blog.japila.pl
Warszawa JUG conference = Confitura (formerly Javarsovia) :: http://confitura.pl

Piotr Zajączkowski

unread,
Jul 8, 2011, 7:09:18 AM7/8/11
to warsza...@googlegroups.com
Też skłaniam się ku opinii, że w powyższym kodzie zastępowanie if-ów
czymś bardziej rozbudowanym jest przerostem formy nad treścią.

A wracając jeszcze do ifów, to jest jedna sprawa, w której się można
"rąbnąć" - mówię o przypadku z pierwszego postu. Otóż jeżeli mamy tam
instanceof-y, to pamiętajmy, że instanceof zwraca true także dla klas
pochodnych (nie tylko wymienionej), zatem istnieje ryzyko, że
świadomie albo nieświadomie umieścimy if-y w złej kolejności i będzie
trudny do wykrycia błąd.
O ile pamiętam, to w Javie 7 ma być dostępny switch po Stringach,
wtedy lepszym rozwiązaniem byłoby "switchowanie" po nazwie klasy
(obj.getClass().getCanonicalName() lub coś takiego...) - jest to
rozwiązanie "przyszłościowe", natomiast wykorzystujące JVM i
mechanizmy języka ;p ;)

Pzdr.

W dniu 8 lipca 2011 12:45 użytkownik mproch Gazeta.pl
<mpr...@gazeta.pl> napisał:

Jacek Laskowski

unread,
Jul 8, 2011, 1:16:55 PM7/8/11
to warsza...@googlegroups.com
2011/7/8 Piotr Zajączkowski <p.m.zaja...@gmail.com>:

> A wracając jeszcze do ifów, to jest jedna sprawa, w której się można
> "rąbnąć" - mówię o przypadku z pierwszego postu. Otóż jeżeli mamy tam
> instanceof-y, to pamiętajmy, że instanceof zwraca true także dla klas
> pochodnych (nie tylko wymienionej), zatem istnieje ryzyko, że
> świadomie albo nieświadomie umieścimy if-y w złej kolejności i będzie
> trudny do wykrycia błąd.

Bardzo dobra uwaga. Faktycznie o tym w ogóle nie myślałem, a może
przysporzyć problemów.

> O ile pamiętam, to w Javie 7 ma być dostępny switch po Stringach,
> wtedy lepszym rozwiązaniem byłoby "switchowanie" po nazwie klasy
> (obj.getClass().getCanonicalName() lub coś takiego...) - jest to
> rozwiązanie "przyszłościowe", natomiast wykorzystujące JVM i
> mechanizmy języka ;p ;)

Ta nowość, to porównywanie po String.equals() (było wczoraj podczas
testu na spotkaniu powitalnym j7) i w zasadzie nie widzę dla tego
zastosowania (poza upiększeniem wyglądu kodu, ale niekoniecznie jego
kształtu).

Wciąż uważam, że jeśli cokolwiek miałbym zmienić w pierwotnym kodzie,
to byłoby to właśnie przeciążanie (i tak zrobię w poprawce). Dzięki za
sugestie.

Piotr Zajączkowski

unread,
Jul 8, 2011, 2:15:05 PM7/8/11
to warsza...@googlegroups.com
W dniu 8 lipca 2011 19:16 użytkownik Jacek Laskowski <ja...@japila.pl> napisał:

> Ta nowość, to porównywanie po String.equals() (było wczoraj podczas
> testu na spotkaniu powitalnym j7) i w zasadzie nie widzę dla tego
> zastosowania (poza upiększeniem wyglądu kodu, ale niekoniecznie jego
> kształtu).

Ok, co kto woli :) Ja bym wolał mieć to w postaci switcha po stringach
a można mieć też drabinkę if-ów ze String.equals().

Krzysztof Daniel

unread,
Jul 9, 2011, 8:39:52 AM7/9/11
to warsza...@googlegroups.com
Jacek,
generalnie wyodrębnienie metod z różnymi sygnaturami jest ok po uwzględnieniu komentarza Irka.
uważam jednak, że należałby się koniecznie przyjrzeć dlaczego item może mieć kilka postaci, bo być może smrodek dochodzi z innego miejsca, a wtedy klasę z tą nieszczęsną metodą być możne da się przekształcić w:

class URLHandler {
   void soSth(URL u){...};
}

class StringHandler extends URLHandler{
   void soSth(String s){
      super.doSth(new URL(s));
   };
}

i wtedy od stworzenia item'a towarzyszy mu odpowiedni handler.  

Z drugiej strony można item sprowadzić do jednego typu w momencie pierwszego z nim kontaktu...
2011/7/8 Piotr Zajączkowski <p.m.zaja...@gmail.com>
--
Otrzymujesz tę wiadomość, ponieważ subskrybujesz grupę dyskusyjną Google o nazwie "Warszawa Java User Group (Warszawa JUG)".

Aby zamieszczać posty w tej grupie, wyślij e-mail na adres warsza...@googlegroups.com.
Aby anulować subskrypcję tej grupy, wyślij e-mail na adres warszawa-jug...@googlegroups.com.
Aby uzyskać więcej informacji, odwiedź tę grupę pod adresem http://groups.google.com/group/warszawa-jug?hl=pl.




--
Krzysztof Daniel
Skype: krzysztof.daniel
GG: 1277601

Sławek Sobótka

unread,
Jul 9, 2011, 8:49:32 AM7/9/11
to Warszawa Java User Group (Warszawa JUG)
Zacznę od tego, że przeciążanie metod nie jest żądną techniką
projektową w Javie ponieważ nie rozwiązuje żadnego problemu. Wciąż
musisz wybrać w czasie kompilacji wywoływaną metodę.
Ot taka błyskotka składniowa co by łowić leszczy na egzaminie SCHWDP
(czy jak to się teraz zwie;)

Co innego w językach, które wspierają double-dispatch
http://en.wikipedia.org/wiki/Double_dispatch


W tym konkretnym przypadku ciężko podać rozwiązanie, bo właśnie
brakuje kontekstu aby uznać go za konkretny - w szczególności czego
się spodziewamy w przyszłości oraz gdzie i przez jaki kod kliencki ma
być używany ten kod.

Intuicja OO może podpowiadać, że mamy to do czynienia ze złą
abstrakcją. Skro mielimy w ten sam sposób Stringa (który można uważać
za typ niemal prymitywny) oraz URL (który jest pojęciem z jakiejś
konkretnej domeny) to "wiedz, że coś się dzieje".
Dobry design prawdopodobnie zostałby oparty na klasie, która adaptuje
oba pojęcia do pojęcia bardziej "biznesowego" czy domenowego w tym
konkretnym kontekście. Rodzaj wrappera, bo Adapter Design pattern to
nie będzie ponieważ nie adaptujemy interfejsu Stringa i URL do
istniejącego wymaganego innego interfejsua. Jest to jedynie wrapper,
który nadaje nowe znaczenie domenowe. Przy okazji ukłon w stronę mikro-
typów wspomnianych przez Bartka K. w innym wątku.

Póki co nie znając kontekstu i zakładając, że:
1. nie spodziewamy się zmian
2. nie jest to publiczne apli, które powinno wyrażać jasne intencje co
do domeny
zostawiłbym tak jak jest.


Sławek Sobótka
http://ssepp.pl
http://art-of-software.blogspot.com

Irek Matysiewicz

unread,
Jul 9, 2011, 12:20:32 PM7/9/11
to warsza...@googlegroups.com
W dniu 2011-07-09 14:49, Sławek Sobótka pisze:

> Zacznę od tego, że przeciążanie metod nie jest żądną techniką
> projektową w Javie ponieważ nie rozwiązuje żadnego problemu. Wciąż
> musisz wybrać w czasie kompilacji wywoływaną metodę.
> (...)

> Co innego w językach, które wspierają double-dispatch
> http://en.wikipedia.org/wiki/Double_dispatch
>

W Javie double dispatch (albo ogólniej: multiple dispatch) można
'emulować' za pomocą wielu technik (na przykładzie Jacka z jego metodą
doSth):

- if-ów: void doSth(Klasa obj) { if(obj instanceof Podklasa1) { ... }
else if(obj instanceof Podklasa2) { ... } }

- switchów: void doSth(Klasa obj) { switch(obj.getTyp()) { case
PODKLASA1: ...; case PODKLASA2: ...} }, dodatkowo Groovy i języki
funkcyjne mają superwypasione wersje switchów

- wzorca Visitor: void doSth(Klasa obj) { obj.accept(new KlasaVisitor()
{ void podklasa1() {...} void podklasa2() { ... } }) }

- fabryczek + wzorca Strategia: void doSth(Klasa obj) {
fabryka.dajMiDoSth(obj.getClass()).wykonaj() }

- modyfikowalnych fabryczek (np. hashmapy, whiteboard pattern, rejestr
Windows): fabryczka[Podklasa1.class] = { kod1 };
fabryczka[Podklasa2.class] = { kod2 }; void doSth(Klasa obj) {
fabryka.dajMiDoSth(obj.getClass()).wykonaj() }

- i właśnie przeciążanie metod: void doSth(Podklasa1 obj) { ... } void
doSth(Podklasa2 obj) { ... }. Akurat w Javie wybór przeciążonej metody
następuje w czasie kompilacji, ale można to przenieść do runtime'u
dodając trzecią metodę: void doSth(Klasa obj) {
getClass().getMethod("doSth", obj.getClass()).invoke(this, obj) }.

- invokedynamic z Javy 7 - jeszcze nie próbowałem, ale to się chyba da
zrobić:
http://download.java.net/jdk7/docs/technotes/guides/vm/multiple-language-support.html
+
http://weblogs.java.net/blog/forax/archive/2011/01/07/calling-invokedynamic-java


To jest tylko wybór narzędzia. Wszystkie robią z grubsza to samo, i
wybór to chyba tylko kwestia czy (i jak) ten kod będzie ewoluował w
przyszłości, wydajności, albo po prostu gustu, i stąd na pytanie Jacka
pojawiło się tyle rozwiązań, ale skoro nie znamy szerszego kontekstu, to
w myśl KISS czy YAGNI stosujemy najprostsze rozwiązanie, a nim jest
właśnie przeciążanie metod, albo if-else. :-)


Jacek Laskowski

unread,
Jul 9, 2011, 12:45:14 PM7/9/11
to warsza...@googlegroups.com
2011/7/9 Sławek Sobótka <sso...@gmail.com>:

> Zacznę od tego, że przeciążanie metod nie jest żądną techniką
> projektową w Javie ponieważ nie rozwiązuje żadnego problemu. Wciąż
> musisz wybrać w czasie kompilacji wywoływaną metodę.

To po co String.valueOf(...) w tylu wydaniach, odpowiednio dla każdego typu?!

http://download.oracle.com/javase/6/docs/api/java/lang/String.html

Jacek Laskowski

unread,
Jul 9, 2011, 12:50:09 PM7/9/11
to warsza...@googlegroups.com
2011/7/9 Krzysztof Daniel <krzyszto...@gmail.com>:

> uważam jednak, że należałby się koniecznie przyjrzeć dlaczego item może mieć
> kilka postaci, bo być może smrodek dochodzi z innego miejsca, a wtedy klasę
> z tą nieszczęsną metodą być możne da się przekształcić w:

Co Wy z tym smrodkiem?! Zaczynam czuć się jak klient, który mówi, że
chce gofra i w zależności od zaawansowania budki słyszy w odpowiedzi
"Proszę", albo "A z jakimi dodatkami, kształtem, smakiem, kolorem,
itp." :)

Różne miejsca powstawania item, to np. pochodzi z warstwy webowej z
żądania (jako String) lub przez zdalne wywołanie RMI (jako Object).

> class URLHandler {
>    void soSth(URL u){...};
> }
> class StringHandler extends URLHandler{
>    void soSth(String s){
>       super.doSth(new URL(s));
>    };
> }
> i wtedy od stworzenia item'a towarzyszy mu odpowiedni handler.

Ale wtedy sprowadza się to efektywnie do instanceof, którą musi
obsłużyć programista. Ja tego nie chcę, bo wiem, że JVM z
przeciążonymi metodami zrobi to za mnie. Moje pierwotne pytanie
zmierzało do znalezienia bardziej zaawansowanego rozwiązania (jeśli
takowe w ogóle istnieje i bez określania, czym "bardziej zaawansowane"
jest).

Irek Matysiewicz

unread,
Jul 9, 2011, 1:34:57 PM7/9/11
to warsza...@googlegroups.com
W dniu 2011-07-09 18:45, Jacek Laskowski pisze:
> 2011/7/9 S�awek Sob�tka<sso...@gmail.com>:
>> Zaczn� od tego, �e przeci��anie metod nie jest ��dn� technik�
>> projektow� w Javie poniewa� nie rozwi�zuje �adnego problemu. Wci��
>> musisz wybra� w czasie kompilacji wywo�ywan� metod�.
> To po co String.valueOf(...) w tylu wydaniach, odpowiednio dla ka�dego typu?!
>
> http://download.oracle.com/javase/6/docs/api/java/lang/String.html
>

Podejrzewam, �e String.valueOf() istnieje z powod�w wydajno�ciowych.
Normalnie wo�asz: obiekt.toString(), ale na typach prymitywnych (int,
long, ...) trzeba coďż˝ w stylu Integer.toString(...). valueOf tak jakby
ukrywa te r�nice: valueOf(cokolwiek) zawsze przerobi to na stringa.
Gdyby nie chodzi�o o wydajno��, to po prostu wystarczy�aby valueOf(Object).
Gdyby to ode mnie zale�a�o, by�oby w Javie tak jak jest w Scali czy w
C#: cokolwiek to jest, zawsze mo�esz wywo�a� obiekt.toString(), a
sprytny kompilator i tak to sam zoptymalizuje - kto� mocno nie pomy�la�
przy tworzeniu pierwszej wersji Javy. Podobnie gdyby nie chodzi�o o
powody wydajno�ciowe, zamiast poprzeci��anych metod, w Math.max()
powinno byďż˝ tam po prostu <T extends Comparable<T>> Math.max(T x, T y).

W valueOf dla czegokolwiek co przeka�esz zachowanie by�o okre�lone
(ka�dy obiekt mo�na przerobi� na stringa), dla wszystkiego co jest
Comparable mo�esz zdefiniowa� zachowanie max. Tw�j przypadek by� nieco
inny: doSth(Object obj) { if(obj instanceof String) { zr�b to } else if
(obj instanceof URL) { zr�b tamto } else { throw new
IllegalArgumentException() } } - nie dla wszystkich dopuszczonych
obiekt�w mamy zdefiniowane zachowanie.

Jest to mniej odporne na b��dy i mniej czytelne dla programisty ni� dwie
przeci��one metody: doSth(String), doSth(URL) - wystarczy wcisn��
ctrl+spacja i wida� o co chodzi, przy doSth(Object) by�oby to mniej
jasne. Cho� wszystkie sposoby robi� to samo, r�ni� si� troch�
(wydajno��, sprawdzenia kompilatora, mo�liwo�� rozbudowy, prostota). Na
czym ci najbardziej zale�y, tak� technik� wybierasz, nie mo�na mie�
wszystkiego na raz.

iirekm

unread,
Jul 9, 2011, 1:36:34 PM7/9/11
to warsza...@googlegroups.com
Omyłkowo znowu zjadłem polskie znaki. Jeszcze raz:

W dniu 2011-07-09 18:45, Jacek Laskowski pisze:
2011/7/9 Sławek Sobótka<sso...@gmail.com>:
Zacznę od tego, że przeciążanie metod nie jest żądną techniką
projektową w Javie ponieważ nie rozwiązuje żadnego problemu. Wciąż
musisz wybrać w czasie kompilacji wywoływaną metodę.
To po co String.valueOf(...) w tylu wydaniach, odpowiednio dla każdego typu?!

http://download.oracle.com/javase/6/docs/api/java/lang/String.html


Podejrzewam, że String.valueOf() istnieje z powodów wydajnościowych. Normalnie wołasz: obiekt.toString(), ale na typach prymitywnych (int, long, ...) trzeba coś w stylu Integer.toString(...). valueOf tak jakby ukrywa te różnice: valueOf(cokolwiek) zawsze przerobi to na stringa. Gdyby nie chodziło o wydajność, to po prostu wystarczyłaby valueOf(Object).
Gdyby to ode mnie zależało, byłoby w Javie tak jak jest w Scali czy w C#: cokolwiek to jest, zawsze możesz wywołać obiekt.toString(), a sprytny kompilator i tak to sam zoptymalizuje - ktoś mocno nie pomyślał przy tworzeniu pierwszej wersji Javy. Podobnie gdyby nie chodziło o powody wydajnościowe, zamiast poprzeciążanych metod, w Math.max() powinno być tam po prostu <T extends Comparable<T>> Math.max(T x, T y).

W valueOf dla czegokolwiek co przekażesz zachowanie było określone (każdy obiekt można przerobić na stringa), dla wszystkiego co jest Comparable możesz zdefiniować zachowanie max. Twój przypadek był nieco inny: doSth(Object obj) { if(obj instanceof String) { zrób to } else if (obj instanceof URL) { zrób tamto } else { throw new IllegalArgumentException() } } - nie dla wszystkich dopuszczonych obiektów mamy zdefiniowane zachowanie.

Jest to mniej odporne na błędy i mniej czytelne dla programisty niż dwie przeciążone metody: doSth(String), doSth(URL) - wystarczy wcisnąć ctrl+spacja i widać o co chodzi, przy doSth(Object) byłoby to mniej jasne. Choć wszystkie sposoby robią to samo, różnią się trochę (wydajność, sprawdzenia kompilatora, możliwość rozbudowy, prostota). Na czym ci najbardziej zależy, taką technikę wybierasz, nie można mieć wszystkiego na raz.


Sławek Sobótka

unread,
Jul 9, 2011, 3:07:26 PM7/9/11
to Warszawa Java User Group (Warszawa JUG)
> To po co String.valueOf(...) w tylu wydaniach, odpowiednio dla każdego typu?!

Jacek, to że toś sobie nazwał metodę valueOf
a nie valueOfInteger
albo
valieOfDouble

to tylko jego wybór.

Nie wiem czy w tym wypadku jest to podyktowane barkiem fantazji czy
jakąś regułą projektowania API. Ale rozumiejąc zasady kompilacji JVM
można bez wątpienia powiedzieć, że wspólna nazwa tej "grupy" metod nie
ma żadnego znaczenia z punktu widzenia wykonania kodu. Można uznać, że
nadanie takiego samego nazewnika dla kilku metod jest nie nieznaczącym
"przypadkiem".

Również z puntu widzenia programisty nie ma to znaczenia ponieważ
programista Java woła w danej linijce kodu konkretną metodę - w sensie
metodę z parametrem konkretnego typu, czy to będzie Double czy
Integer. Kompilator sprawdza typ a w czasie kompilacji masz wiązanie
wywołania konkretnej metody. Tak więc to czy metoda nazywa się
valueOf, czy valueOfInteger jest szczegółem, bo może się nazywać
zróbMiDobrze byle tylko miała parametry znane z czasu kompilacji.
Jeszcze raz zachęcam do poczytania na wiki o double-dispatch, to
powinno wyjaśnić kiedy typ parametru robi różnicę przy metodach o tej
samej nazwie.

Z tego powodu przeciążanie metod nie jest techniką projektowania, jest
jedynie jedną z możliwych konwencji nazywania metod.

Sławek Sobótka

unread,
Jul 9, 2011, 3:12:32 PM7/9/11
to Warszawa Java User Group (Warszawa JUG)
Irek znamy się, więc wiesz dobrze, że ja to wszystko wiem i rozumiem.
Jednak Double dispatch to element składni. Oczywiście, że można go
sobie "emulować" domowymi sposobami (pod spodem na maszynie nie
uciekniemy pewnie od jakiejś tablicy wskaźników), ale wówczas nie
będzie to już element składni, tylko własna konwencja.
> zrobić:http://download.java.net/jdk7/docs/technotes/guides/vm/multiple-langu...
> +http://weblogs.java.net/blog/forax/archive/2011/01/07/calling-invoked...

Irek Matysiewicz

unread,
Jul 9, 2011, 4:53:24 PM7/9/11
to warsza...@googlegroups.com
W dniu 2011-07-09 21:07, Sławek Sobótka pisze:

>> To po co String.valueOf(...) w tylu wydaniach, odpowiednio dla każdego typu?!
> Jacek, to że toś sobie nazwał metodę valueOf
> a nie valueOfInteger
> albo
> valieOfDouble
>
> to tylko jego wybór.
Nie zawsze to jest wybór.

W String.valueOf() w Math.max() to prawdopodobnie nie wybór tylko
optymalizacja polimorfizmu jak pisałem wcześniej:
String.valueOf(Object) działa zarówno na typach prymitywnych jak i
referencyjnych, ale w przypadku typów prymitywnych wymaga autoboxingu
(np. int -> Integer), a boxing wymaga alokacji obiektu, a alokacja
obiektu choć w Javie jest bardzo szybka, i tak jest duuużo wolniejsza od
wywołania metody, a zbędnego boxingu optymalizować nie potrafi ani javac
ani HotSpot JVM (tak przynajmniej było z pół roku temu), i m.in. z tego
powodu metody te są dodatkowo poprzeciążane dla wszelakich typów
prymitywnych: valueOf(int), valueOf(long), itd. Jeśli typ znany jest w
czasie kompilacji zostanie użyta zoptymalizowana wersja przeciążona, a
jeśli nie, to trudno - następi boxing i unboxing.

Kompilator Scali potrafi dokonywać takich paskudnych optymalizacji
automatycznie: bierze zróbCoś(T) i potrafi automatycznie to
"wyspecjalizować" dla wszystkich typów prymitywnych (zróbCoś(int),
zróbCoś(long), ...).

Irek Matysiewicz

unread,
Jul 9, 2011, 5:18:01 PM7/9/11
to warsza...@googlegroups.com
W dniu 2011-07-09 21:12, Sławek Sobótka pisze:

> Irek znamy się, więc wiesz dobrze, że ja to wszystko wiem i rozumiem.
> Jednak Double dispatch to element składni. Oczywiście, że można go
> sobie "emulować" domowymi sposobami (pod spodem na maszynie nie
> uciekniemy pewnie od jakiejś tablicy wskaźników), ale wówczas nie
> będzie to już element składni, tylko własna konwencja.

Ja wiem że ty wiesz, ty wiesz że ja wiem, ale jest tu kilkaset osób i na
pewno nie wszyscy wiedzą. :-)

Co prawda Java nie wspiera double dispatch, ale z drugiej strony użycie
tego sposobu z refleksją do emulacji double dispatch nie jest takie
trudne, wobec tego przeciążanie metod w Javie nie jest takie złe. (co
innego np. w C++ - tam trik z refleksją nie zadziała bo standardowy C++
refleksji nie ma)

Sławek Sobótka

unread,
Jul 10, 2011, 2:10:43 PM7/10/11
to Warszawa Java User Group (Warszawa JUG)
> ...
> Jeśli typ znany jest w
> czasie kompilacji zostanie użyta zoptymalizowana wersja przeciążona, a
> jeśli nie, to trudno - następi boxing i unboxing.

Nie no jasne.
Ale mnie się rozchodzi o coś z goła innego.
Przeciążanie metod nie jest techniką projektowania tak jak dla
przykładu taką techniką jest nadpisywanie metod i ich polimorficzne
wywołanie. Może zdefiniuję co rozumiem pod pojęciem "być techniką" -
wnosić jakąś wartość do sprawy.

Mechanizmy, o których piszesz mogłyby działać bez żadnej zmiany oraz
wpływu na sposób rozumowa programisty gdyby "API" Stringa wyglądało
tak:
- valueOf(Object)
- valueIfInt(int)
bo wybór przeciążonej metody następuje podczas kompilacji na podstawie
typu.


ale ale

jak zwykle odpływamy od brzegu;P
(zawsze daję się Irkowi uwikłać w żeglugę na wodach bliskich
kompilatora;)

Co sądzicie o mojej propozycji rozwiązania polegającego na
wprowadzeniu typu, który nadaje sens w danej domenie - oczywiście przy
założeniu (tak jak pisałem), że kod będzie ulegał zmianom oraz, że
jest to znaczące api.

Irek Matysiewicz

unread,
Jul 10, 2011, 4:14:09 PM7/10/11
to warsza...@googlegroups.com
W dniu 2011-07-10 20:10, Sławek Sobótka pisze:

>
>
> ale ale
>
> jak zwykle odpływamy od brzegu;P
Temat główny wydaje mi się już wyczerpany: za mało mamy szczegółów o
problemie by w ogóle dyskutować jakie rozwiązanie będzie najlepsze.

> (zawsze daję się Irkowi uwikłać w żeglugę na wodach bliskich
> kompilatora;)

Bo kompilatory i języki programowania, i ich jakość określają sposób w
jaki myślimy o kodzie i ogólnie wpływają na jakość naszej pracy.
Kompilator to najważniejsze narzędzie programisty: bez Eclipsa jakośtam
przeżyjesz, bez Bugzilli jakośtam przeżyjesz, bez SVN-a i Mavena
jakośtam przeżyjesz, bez JUnita jakośtam przeżyjesz, ale bez kompilatora
raczej niewiele zdziałasz.

Dla przykładu, zespół do którego teraz trafiłem w pracy nie używa ani
Bugzilli (czy czegokolwiek podobnego), ani Mavena (czy czegokolwiek
podobnego), ani JUnita (czy czegokolwiek podobnego), ani nawet SVN-a
(czy czegokolwiek podobnego - wymiana i integracja kodu odbywa się
mejlem), choć oczywiście o wiele, wiele lepiej by było gdyby te
narzędzia były też używane, ale dobry język programowania i kompilator
(czy interpreter) to absolutna podstawa, a im lepszy tym lepiej, dlatego
zawsze warto pogłębiać wiedzę z tego tematu.

Sławek Sobótka

unread,
Jul 10, 2011, 6:57:04 PM7/10/11
to Warszawa Java User Group (Warszawa JUG)
OMFG

ags

unread,
Jul 10, 2011, 7:29:20 PM7/10/11
to warsza...@googlegroups.com
Zdaje się Adam Bien opowiadał, jak kiedyś po prezentacji na której udawał, że pisze klasy w hexie, podeszli do niego ludzie, czy tak by nie mogli u nich programiści, bo te IDE drogie.

2011/7/10 Irek Matysiewicz <iir...@gmail.com>
--
Otrzymujesz tę wiadomość, ponieważ subskrybujesz grupę dyskusyjną Google o nazwie "Warszawa Java User Group (Warszawa JUG)".

Aby zamieszczać posty w tej grupie, wyślij e-mail na adres warsza...@googlegroups.com.
Aby anulować subskrypcję tej grupy, wyślij e-mail na adres warszawa-jug+unsubscribe@googlegroups.com.

Aby uzyskać więcej informacji, odwiedź tę grupę pod adresem http://groups.google.com/group/warszawa-jug?hl=pl.




--
ags

Michał Bartyzel

unread,
Jul 11, 2011, 7:44:26 AM7/11/11
to warsza...@googlegroups.com
czu�em w ko�ciach, �e na zwyczajnym "pytanie - odpowied�" si� nie sko�czy:)

W dniu 2011-07-06 21:59, Jacek Laskowski pisze:
> Cze��,
>
> W�a�nie trafi�em na poni�szy kawa�ek kodu i przyku� moj� uwag�, bo w
> zasadzie "zmusi�" mnie, aby go zamieni� na rozwi�zanie z metodami
> przeci��onymi.
>
> Ten kawa�ek kodu:
>
> if (item instanceof URL) {
> ...
> } else if (item instanceof String) {
> ...
> } else...
>
> zamieni�bym na:
>
> void doSth(URL url)
> void doSth(String url)
>
> Jakie s� wady/zalety mojej zmiany? S� �adniejsze rozwi�zania? Ch�tnie
> wys�ucha�bym bardziej obitych w projektach i moli ksi��kowych nt.
> projektowania.
>
> Jacek
>

Jacek Laskowski

unread,
Jul 11, 2011, 7:47:47 AM7/11/11
to warsza...@googlegroups.com
2011/7/11 Michał Bartyzel <mbartyz...@gmail.com>:
> czułem w kościach, że na zwyczajnym "pytanie - odpowiedź" się nie skończy:)

Aż dziw bierze, że wciąż tak niewielu się dało ponieść fantazji
programistycznej i wziąć udział w dyskusji :)

Jakub Nabrdalik

unread,
Jul 11, 2011, 8:56:42 AM7/11/11
to warsza...@googlegroups.com, Jacek Laskowski
W dniu 11.07.2011 13:47, Jacek Laskowski pisze:

> 2011/7/11 Michał Bartyzel<mbartyz...@gmail.com>:
>> czułem w kościach, że na zwyczajnym "pytanie - odpowiedź" się nie skończy:)
>
> Aż dziw bierze, że wciąż tak niewielu się dało ponieść fantazji
> programistycznej i wziąć udział w dyskusji :)

Niektórzy w poniedziałek pracują :]


--
Jakub Nabrdalik
http://solidcraft.eu

Jacek Laskowski

unread,
Jul 11, 2011, 9:09:15 AM7/11/11
to Warszawa-JUG
2011/7/11 Jakub Nabrdalik <jak...@gmail.com>:

> Niektórzy w poniedziałek pracują :]

Zakładam, że na tej grupie "niektórzy" to "wszyscy". To jest forum
WJUGa, a nie MiToLotto czy NieMamKredytuPracaToHobby :)

Sławek Sobótka

unread,
Jul 11, 2011, 9:45:45 AM7/11/11
to Warszawa Java User Group (Warszawa JUG)
> Zakładam, że na tej grupie "niektórzy" to "wszyscy". To jest forum
> WJUGa, a nie MiToLotto czy NieMamKredytuPracaToHobby :)

No i jeszcze SadoMasoPoCoMiRepoKokodzamboIDoPrzodu

Bartek Kuczyński

unread,
Jul 11, 2011, 9:47:26 AM7/11/11
to warsza...@googlegroups.com
A nie można prościej...

Jestem scrpting kid od PHP...

Pozdrawiam
Bartek "Koziołek" Kuczyński
http://koziolekweb.pl
Lepiej pomyśleć dwa razy i zacząć programować
niż dwa razy programować i potem zacząć myśleć
 \     /
 ~00~
  \_/
   |||

> --
> Otrzymujesz tę wiadomość, ponieważ subskrybujesz grupę dyskusyjną Google o nazwie "Warszawa Java User Group (Warszawa JUG)".
>
> Aby zamieszczać posty w tej grupie, wyślij e-mail na adres warsza...@googlegroups.com.

> Aby anulować subskrypcję tej grupy, wyślij e-mail na adres warszawa-jug...@googlegroups.com.

Paweł Lipiński

unread,
Jul 11, 2011, 10:55:12 AM7/11/11
to warsza...@googlegroups.com
Eee, Irka i tak nikt nie przebije - wysyłanie kodu mailem
while(true) System.out.println("HiHiHiHiHi");

Paweł

Ps. Hi parę razy, bo to optymalizacja.

Reply all
Reply to author
Forward
0 new messages