Java: Czego mi brak: Operator warunkowy

3 wyświetlenia
Przejdź do pierwszej nieodczytanej wiadomości

Lasu

nieprzeczytany,
8 gru 2008, 10:03:348.12.2008
do Polish Java User Group
Witam!

A więc brakuje mi operatora który by działał jak '.' z małym wyjątkiem
jeśli nadrzędny obiekt byłby null-em, wówczas null byłby zawsze
zwracany. Było by to pozytywne gdy komuś nie chce się deklarować tony
niepotrzebnych zmiennych tylko po to, żeby zajrzeć co jest w środku.
W bardziej skomplikowanych przypadkach niż ten niżej często aby
uniknąć zagrożenia wynikającego z możliwości użycia nieodpowiedniego
pola jest konieczność wydzielania sztucznych bloków tylko po to alby
zmienne się nie walały po metodzie.
Przykład użycia:

public class Test {

public static class SomeHouse {
public MainEntry mainEntry;
}

public static class MainEntry {
public RealyRealyGoodLock realyRealyGoodLock;
}

public static class RealyRealyGoodLock {
public LockMode lockMode;
}

public static class LockMode {

}

/**
* Good and hard
*/
public static LockMode getLockModeStandard(SomeHouse someHouse) {
if (someHouse == null) { return null; }
MainEntry mainEntry = someHouse.mainEntry;
if (mainEntry == null) { return null; }
RealyRealyGoodLock rGoodLock = mainEntry.realyRealyGoodLock;
if (rGoodLock == null) { return null; }
return rGoodLock.lockMode;
}

/**
* Can case some efficiency problems if <code>null</code> occurs
really often.
*/
public static LockMode getLockModeBad(SomeHouse someHouse) {
try {
return someHouse.mainEntry.realyRealyGoodLock.lockMode;
} catch (NullPointerException e) {
return null;
}
}

/**
* This will do not work properly while changing from other thread
*/
public static LockMode getLockModeWorst(SomeHouse someHouse) {
if (someHouse == null) return null;
if (someHouse.mainEntry == null) return null;
if (someHouse.mainEntry.realyRealyGoodLock == null) return null;
return someHouse.mainEntry.realyRealyGoodLock.lockMode;
}

/**
* Would be better
*/
public static LockMode getLockModeSuggested(SomeHouse someHouse) {
return someHouse.?.mainEntry.?.realyRealyGoodLock.?.lockMode;
}

/**
* Would be better
*/
public static LockMode getLockModeSuggestedOther(SomeHouse
someHouse) {
LockMode lockMode
=someHouse.?.mainEntry.?.realyRealyGoodLock.?.lockMode;
if (lockMode==null){
// Do what u want
}
return lockMode;
}

/**
* Mixed case where we know that {@link
MainEntry#realyRealyGoodLock}
* is mandatory and should never happen for this field to be null.
*/
public static LockMode getLockModeMixed(SomeHouse someHouse) {
return someHouse.?.mainEntry.realyRealyGoodLock.?.lockMode;
}
}

--
Pozdrowionka
Lasu <Marek Kozieł>

Paweł Stawicki

nieprzeczytany,
8 gru 2008, 16:39:528.12.2008
do polish-java...@googlegroups.com
No przydałoby się coś takiego. Eeech, w rubym nawet null jest obiektem ;)

Pozdrawiam
--
Pawel Stawicki
http://pawelstawicki.blogspot.com

Arkadiusz Borek

nieprzeczytany,
8 gru 2008, 17:01:138.12.2008
do polish-java...@googlegroups.com

witam,
 nie powinniśmy negować każdego pomysłu jaki przedstawia nam Lasu; sorry, że tak mowie ale narazie zobaczyłem argumenty która pokazywały co złego taki operator zrobił by z podstawowymi założeniami paradygmatu obiektowego, ale wracając do realnego świata;

przykład numer jedne:
mamy zdefiniowanego enuma który to zawiera pola code i name;
i jeżeli chcemy pobrać wartość code z niego to musimy za każdym razem sprawdzać czy nie jest on null;

przykład numer dwa:
sam sun opracował technologie taka jak jaxb(parsowanie xmla do struktury class) i o to w tej technologi sun traktuje klasy jako składnice danych gdzie 'olewa' enkapsulację, wiec nie wiem dlaczego nam nie może ułatwić życia; sama struktura to często po 9 zagnieżdżeń które defakto wynikają z struktury xml'a; 


ps. jeżeli ktoś chce sobie zorbić kuku to wystraczy mu instrukcja przypisania i zorbi sobie kuku;


--
Arkadiusz Borek

Paweł Stawicki

nieprzeczytany,
8 gru 2008, 18:00:448.12.2008
do polish-java...@googlegroups.com

 nie powinniśmy negować każdego pomysłu jaki przedstawia nam Lasu; sorry, że tak mowie ale narazie zobaczyłem argumenty która pokazywały co złego taki operator zrobił by z podstawowymi założeniami paradygmatu obiektowego,


Ale gdzie? Czyżbym jakichś maili nie dostał?

Pozdrawiam
Paweł Stawicki

Lasu

nieprzeczytany,
8 gru 2008, 18:28:438.12.2008
do Polish Java User Group
On 9 Gru, 00:00, "Paweł Stawicki" <pawelstawi...@gmail.com> wrote:
> Ale gdzie? Czyżbym jakichś maili nie dostał?
>
> Pozdrawiam
> Paweł Stawicki

na LJUG jest tego więcej:
http://groups.google.com/group/lublin-jug/browse_thread/thread/ea6b11dbc0b297d1?hl=pl

Wiktor Gworek

nieprzeczytany,
14 gru 2008, 11:11:3914.12.2008
do polish-java...@googlegroups.com
Raczej nie jest to dość uciążliwe. Z języków mi znany to taki operator ma tylko Groovy. Operator '.?'. Przekazywanie nulli do metod nie jest dobre. Polecam 2 rozwiązania:

1) http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/base/Preconditions.html - używanie asercji w czasie uruchomienia programu

lub

2) Używanie wzorca NullObject.

W.

2008/12/8 Lasu <develo...@gmail.com>

kriswpl

nieprzeczytany,
15 gru 2008, 05:11:5415.12.2008
do Polish Java User Group
uwazam, ze nie brakuje nic - rozwiazania takie jak Wiktor pokazuje jak
najbardziej jest wystarczajace - szczegolnie asercje - to one pokazuej
od razu jakie sa zalozenia metody na wstepie (czy moze wogole wpasc
null czy nie). Bo przeciez gdzieniegdzie nie ma szans ze wpadnie null,
a gdzieniegdzie trzeba rownie sie zachowac jakby wpadl. Twoj przyapdek
Lasu jest troche z pogranicza takiego walidatora.

Natomiast chcialbym zauwazyc jedna bardzo wazna rzecz - Lasu,
zagniezdziles kilka klas - fajnie troche obiektowowsci w tym widac,
ale dlaczego rowniez nie delegujesz odwolania sie do tych klas - tylko
przecinasz przez wszystkie obiekty zeby sie dostac do jakiejs
zmiennej. Mnie to nie ladnie wyglada, po co Ci na wysokim poziomie
jakas zmienna (atrybut) z klasy 3 razu zagniezdzonej - sprobuj napisac
bardziej obiektowo metode - delegujac pewne zachowania do odpowiednich
klas.

KW


On 14 Gru, 17:11, "Wiktor Gworek" <wiktor.gwo...@gmail.com> wrote:
> Raczej nie jest to dość uciążliwe. Z języków mi znany to taki operator ma
> tylko Groovy. Operator '.?'. Przekazywanie nulli do metod nie jest dobre.
> Polecam 2 rozwiązania:
>
> 1)http://google-collections.googlecode.com/svn/trunk/javadoc/com/google...
> używanie asercji w czasie uruchomienia programu
>
> lub
>
> 2) Używanie wzorca NullObject.
>
> W.
>
> 2008/12/8 Lasu <develop4l...@gmail.com>

Lasu

nieprzeczytany,
16 gru 2008, 09:11:1916.12.2008
do Polish Java User Group
On 14 Gru, 17:11, "Wiktor Gworek" <wiktor.gwo...@gmail.com> wrote:
> 1)http://google-collections.googlecode.com/svn/trunk/javadoc/com/google...
> używanie asercji w czasie uruchomienia programu

A co jeśli chcem pozwolić na to żeby null był.

> 2) Używanie wzorca NullObject.
Daje możliwość uzyskania NullPointerException, nawet pomimo validacji.

On 15 Gru, 11:11, kriswpl <kris...@gmail.com> wrote:
> Mnie to nie ladnie wyglada, ...
Mnie też, ale to tylko przykład.

wiktor...@gmail.com

nieprzeczytany,
16 gru 2008, 12:16:5716.12.2008
do polish-java...@googlegroups.com, Polish Java User Group
W ten sposób można argumentować wszystko. To jest kwestia
zaprojektowania aplikacji. Polecam przeczytanie na wikipedii o "law of
demeter".



W dniu 2008-12-16, o godz. 15:11, Lasu <develo...@gmail.com>
napisał(a):

Lasu

nieprzeczytany,
17 gru 2008, 04:51:0717.12.2008
do Polish Java User Group
Ja niczemu nie przeczę.
Stwierdzam ino, że świat nie jest idealny i nie idealne sytuacje
wymagają odpowiednich narzędzi.

Przecie nikt nie wyrzuca gnoju widelcem.
A dla mnie dyskusja zamiast jak wyrzucać gnój zmienia się w dyskusje
po co wyrzucać gnój.
Odpowiedz jest bardzo prosta:
Bo czasem trzeba i nie chcę wtedy żonglować widelcem, to to już
przekłada się na to ile ostatecznie czasu spędzisz w tym mniej bądź
bardziej nieprzyjemnym zadaniu.

A, że takowe się zdarzają, to nie jeden programista potwierdzi.

Waldek Kot

nieprzeczytany,
17 gru 2008, 19:04:4617.12.2008
do Polish Java User Group
On 17 Gru, 10:51, Lasu <develop4l...@gmail.com> wrote:
> Stwierdzam ino, że świat nie jest idealny i nie idealne sytuacje
> wymagają odpowiednich narzędzi.

Lasu - a to rozwiązanie, które podałem na pl.comp.lang.java - czyli z
użyciem AOP ? Wydaje się spełniać to o czym piszesz ???


Tak się też zresztą zastanawiałem, że użycie AOP mogłoby dać tu
jeszcze większy hardcore, czyli automatyczne utworzenie NullObject.
Byłoby to użyteczne tam, gdzie ktoś chce zastosować wzorzec NullObject
(a nie chce użyć Groovy bądź tego aspektu, który podałem wcześniej).
Wyobrażam sobie to tak, żeby stworzyć aspekt, który wyłapywałby
wszystkie metody zwracające określone obiekty ("określone" czyli tej
klasy dla której ma być utworzony NullObject) i jeśli zwracana wartość
jest równa null, to zamiast tego zwracać dynamicznie utworzony obiekt
NullObject danej klasy. Do dynamicznego utworzenia takiego obiektu
możnaby użyć np. refleksji (dynamic proxy) - to by pozwoliło
skonstruować "normalny" obiekt, czyli także zachować np. hierarchię
dziedziczenia (Nullxxx dziedziczy po xxx, itd).
Plus takiego podejścia, to brak konieczności tworzenia w sposób
explicite klas NullObject (czyli Nullxxx, Nullyyy do klas xxx, yyy) -
trochę sztucznych jednak ("technicznych"). Minus, to - jak to często
bywa w AOP - trzeba jakoś zakomunikować, że dla wybranych klas,
znaczenie null jest trochę inne i oznacza w zasadzie NullObject danej
klasy. Pewnie też z racji dynamicznego tworzenia obiektu Null trochę
będzie gorsza wydajność, ale pewnie dałoby się to znacznie zredukować
przez posłużenie się singletonem i tworzyć obiekt Null w momencie
pierwszego użycia null danego typu (a może i jeszcze wcześniej, ale tu
nie mam pomysłu jak - może w momencie ładowania klasy, dla której ma
być utworzony jej potomek Null ???). Inny plus (ale to znowu raczej
jest plus AOP niż tego pomysłu), że to się da zaaplikować do
istniejącego kodu (np. takiego, w którym chcemy się pozbyć
NullPointerException, ale nie mamy dostępu do kodu źródłowego albo nie
możemy go zmodyfikować)...
Nie wiem - co myślicie - bredzę ;-) ?

Pozdrawiam,
Waldek Kot

PS
Link do pomysłu aspektu podany na pl.comp.lang.java:
http://groups.google.com/group/pl.comp.lang.java/tree/browse_frm/thread/d290ced113686b34/922a8c665ece774e?rnum=11&q=aspectj&_done=%2Fgroup%2Fpl.comp.lang.java%2Fbrowse_frm%2Fthread%2Fd290ced113686b34%2Fe6f904ca769e546a%3Flnk%3Dgst%26q%3Daspectj%26#doc_e6f904ca769e546a

Lasu

nieprzeczytany,
18 gru 2008, 02:29:3018.12.2008
do Polish Java User Group
Hey!

Właściwie to myślałem o czymś takim. ;P
Tylko to ja sobie trochę inaczej postawiłem pytanie, a mianowicie co
chciałbym przez to osiągnąć. I okazało się że docelowo jeśli byśmy
zrobili null-object to okazało by się że jest potrzeba jego pełnego
zastosowania.
Już wyjaśniam o co mi biega.
1. Musieli byśmy odróżniać null-object od innego obiektu.
2. Czasami Null skoro jest obiektem, musiał by zwracać jakieś
konkretne wartości np. czasem 5 odpowiada 0 / -1 == nie znaleziono.
3. Są przypadki dla których nie ma jednoznacznej definicji jakiego
typu obiekt powinien być zwrócony a wtedy znów musieli byśmy używać
'.?.'

Tak więc uważam że dało by to nowe możliwości ale też stworzyło by to
sporo problemów.
Min. generyczne mogły by się okazać kulą u nogi, zwłaszcza z ich
obecnym sposobem obsłużenia przez JVM.

Co do samego AOP którego nie lubię ;P gdyż ukrywa pewne zależności, to
jestem zdania, że to załatwiło by sprawę ale zbyt dużym kosztem i
zapewne by się okazało, że ludzie wolą pozostać przy starch
NullPointerException.
Ale jak się okaże, że będzie mi do czegoś potrzebny to pewnie zmienię
zdanie co do sensowności istnienia AOP ;).

Pozdrowionka!
Lasu <Marek Kozieł>
> Link do pomysłu aspektu podany na pl.comp.lang.java:http://groups.google.com/group/pl.comp.lang.java/tree/browse_frm/thre...

Waldek Kot

nieprzeczytany,
20 gru 2008, 09:20:0620.12.2008
do Polish Java User Group
On 18 Gru, 08:29, Lasu <develop4l...@gmail.com> wrote:
> Co do samego AOP którego nie lubię ;P gdyż ukrywa pewne zależności, to
> jestem zdania, że to załatwiło by sprawę ale zbyt dużym kosztem i
> zapewne by się okazało, że ludzie wolą pozostać przy starch
> NullPointerException.

Przypadkiem natrafiłem na realizację pomysłu NullObject poprzez AOP -
http://www.artima.com/weblogs/viewpost.jsp?thread=43091 - w sumie
dosyć podobny pomysł, który opisałem wcześniej, z tym, że tutaj
autorowi bardziej zależało na szybszej i łatwiejszej identyfikacji
miejsc w których "powstał" null pointer. Ma to więc służyć raczej
wyeliminowaniu tych miejsc z kodu, a ja myślałem bardziej o
automatycznej obsłudze null poprzez dynamiczne tworzenie NullObject...

Co do ukrywania zależności przez AOP - z całą pewnością jest to
problem, z którym trzeba się jakoś zmierzyć przy korzystaniu z AOP.
Czasem wystarczy dobra komunikacja między deweloperami, na pewno
pomogą dokumentacja projektowa, czy komentarze w kodzie, itd. Myślę,
że całkiem dobry pomysł to użyć adnotacji do tego, aby zasygnalizować,
że dana klasa, czy metoda podlega jeszcze dodatkowemu "przetwarzaniu"
przez AOP - adnotacje są blisko kodu, mogą być zarówno widoczne na
poziomie źródła, jak i być zapisane w byte-kodzie klasy, dają się
"zobaczyć" z poziomu zewnętrznych narzędzi i poprzez refleksję...
Także pointcut'y w aspektach mogą wykorzystywać adnotacje (i wybierać
tylko te miejsce w kodzie, które są opisane przez konkretną
adnotację).

Co do kosztów AOP, chyba lepiej zamiast o koszcie mówić o inwestycji.
I też prawdę mówiąc, poza koniecznością poznania tej techniki i jej
implementacji (np. AspectJ), to niezbyt widzę inne koszty. Wsparcie w
IDE (np. AJDK), load-time weaving, czy adnotacje (myślę tu o @Aspect)
- a zwłaszcza wsparcie dla AOP, które daje Spring - znacznie
upraszczają pracę z AOP i ten dodatkowy koszt (inwestycji) obniżają. A
już na pewno w zestawieniu z kosztem NPE, bo NPE niemal zawsze oznacza
niewykryty wcześniej bug w kodzie...

Pozdrawiam,
Waldek Kot

Piotr Paradziński

nieprzeczytany,
2 sty 2009, 17:32:162.01.2009
do polish-java...@googlegroups.com
@Lasu

1)
z tego co rozumiem chcesz rozwiązać następujący problem. Masz
zagnieżdżone obiekty i nie chce Ci się pisać kodu sprawdzającego czy
wszystkie elementy po drodze nie są null ale jakby się gdzieś null'ek
zdarzył to nie ma co płakać i ciskać wyjątkami tylko zwrócić takiego
nulka.

Ja spotkałem ten problem przy nietrywialnej logice biznesowej i tzw
anemicznym modelu (czyli POJO zawierające jedynie prywatne pola +
gettery/settery +konstruktory).

Problem z tym sprawdzaniem null'i na każdym poziomie też mnie mocno
spieniał. Tym bardziej, że pojawiał się wielokrotnie.

Może nie najlepszym ale dosyć dobrym rozwiązaniem jest zmusić obiekty
aby na każdym poziomie sprawdzały same czy nie ma null'a.

Oto przykładowe rozwiązanie:

public class Test {

public static class SomeHouse {

private MainEntry mainEntry;

public MainEntry getMainEntry() {
return mainEntry;
}

public void setMainEntry(MainEntry mainEntry) {
this.mainEntry = mainEntry;
}

public LockMode getLockMode() {


if (mainEntry == null)
return null;

return mainEntry.getLockMode();
}

}

public static class MainEntry {

private RealyRealyGoodLock realyRealyGoodLock;

public RealyRealyGoodLock getRealyRealyGoodLock() {
return realyRealyGoodLock;
}

public void setRealyRealyGoodLock(RealyRealyGoodLock realyRealyGoodLock) {
this.realyRealyGoodLock = realyRealyGoodLock;
}

public LockMode getLockMode() {
if (realyRealyGoodLock == null)
return null;
return realyRealyGoodLock.getLockMode();
}
}

public static class RealyRealyGoodLock {

private LockMode lockMode;

public LockMode getLockMode() {
return lockMode;
}

public void setLockMode(LockMode lockMode) {
this.lockMode = lockMode;
}

}

public static class LockMode {
}

/**
* Hard


*/
public static LockMode getLockModeStandard(SomeHouse someHouse) {
if (someHouse == null) {
return null;
}
MainEntry mainEntry = someHouse.mainEntry;
if (mainEntry == null) {
return null;
}
RealyRealyGoodLock rGoodLock = mainEntry.realyRealyGoodLock;
if (rGoodLock == null) {
return null;
}
return rGoodLock.lockMode;
}

/**
* Not so hard
*/
public static LockMode getLockMode2(SomeHouse someHouse) {
if(someHouse == null) return null;
return someHouse.getLockMode();
}
}

Zamieniłem wszystkie publiczne pola na prywatne i dorzuciłem pary
getter/setter co nie było zbyt pracochłonne bo wygenerowało je za mnie
IDE. A do tego gettery nie są trochę rozgarnięte więc sprawdzają czy
przez przypadek obiekt, którym się opiekują nie jest null. Dzięki temu
na każdym poziomie sprawdzasz tylko raz czy jest null.

2)
W większości problemów zamiast dostarczać obiektom klasy SomeHouse
metody getLock() i umożliwieniu użytkownikom tej klasy zrobienia
paskudnych rzeczy z tym zamkiem: np naplucia, wepchnięcia peta itd
lepiej zrobić inaczej. Zaimplementować dla obiektu SomeHouse metody
typu lockHouse() i unlockHouse() czy isLocked() a to że one sobie
korzystają z klasy Lock to już wie tylko osoba implementująca a w
żądnym razie nie musi o tym wiedzieć użytkownik.

I większość osób piszących że naruszasz zasady OOP miała chyba to na myśli.

3)
Niestaty jak zauważa nawet międzynarodowy terrorysta obiektowy A.
Hollub są problemy w których nie da się ładnie programować zgodnie z
zasadami OOP (czyli np robić myki opisane w punkcie 2) i tyle.
Klasyczny przykładem jest tu właśnie dostarczenie ogólnej biblioteki
parsowania XML.

4)
Z tego co obserwuję Twoje posty to większość problemów jakie zgłaszasz
dotyczą raczej zagadnień stricte algorytmicznych. Ja osobiście
wychodzę z założenia iż nie ma sensu aby zarywał noce wkuwając
"Wprowadzenie do algorytmów" Cormen'a lub spędzić kilka lat na
analizowanie wszystkich tomów "Art of Computer Programming" D. Knuth'a
bo i tak to już ktoś zrobił i zrobił to pewnie lepiej a nawet jak nie
to i tak już inni to poprawili. Skupiam swoją uwagę na narzędziach,
frameworkach, efektywnych metodach tworzenia dobrego oprogramowania
itd. Myślę że takie podejście nie jest specyficzne tylko dla mnie.
Proponuję abyś Ty też spróbował.

Ale ponieważ każdy człowiek jest inny więc jeśli nie chcesz i Ciebie
bardziej kręci optymalizacja i algorytmy - OK ale zwróć uwagę na to,
iż język programowania Java jest dosyć kiepski w tym zakresie. Dużo
lepsze możliwości daje np. C/C++.

Jeżeli lubisz elastyczne języki może warto by programować w
JavaScript, Perl (ostrzegam eval() uzależnia :) czy choćby wspominany
Groovy.

Albo w najbardziej wykoksanym uber pro języku Lisp w którym sam
definiujesz konstrukcje typu if, switch, for :D (uczyłem się go tylko
kilka dni ale moje postrzeganie rzeczywistości nigdy już nie będzie
takie samo :)

A jeżeli chcesz zostać przy języku Java i zmienić kilka elementów to
proponuję rzucić okiem na projekty z serii: Apache Commons:
http://commons.apache.org/

Chłopaki i dziewczyny z ASF stwierdzili że można by poprawić JDBC
(http://commons.apache.org/dbutils/), kolekcje
(http://commons.apache.org/collections/). W sprawie transakcji
(http://commons.apache.org/transaction/) też mają swoje 3 grosze do
dorzucenia nie wspominając o obsłudzie typów podstawowych
(http://commons.apache.org/primitives/) algorytmów
(http://commons.apache.org/math/) ... i najlepsze na koniec: samej
składni języka Java: http://commons.apache.org/lang/.

Wydaje mi się, że na forach/listach mailingowych tych projektów
znalazł byś lepszych słuchaczy bo tam ludzie rozwiązują takie problemy
a tu wypowiadają się ludzie którzy są bardziej skłonni do ewentualnego
korzystania z nich a nie do ich pisania.

Nie wiem czy to dobry pomysł. Ostatnio ktoś zwrócił mi uwagę, że zbyt
często zabieram głos w sprawach w których jestem niekompetentny. Więc
może tu też głupoty wciskam :D Mam nadzieję że tak nie jest i że udało
mi się pomóc.

Pozdrawiam

W dniu 20 grudnia 2008 15:20 użytkownik Waldek Kot
<walde...@googlemail.com> napisał:

--
Piotr Paradziński
Lublin JUG: http://lublin.jug.pl
Blog: http://it-researches.blogspot.com/

Odpowiedz wszystkim
Odpowiedz autorowi
Przekaż
Nowe wiadomości: 0