Widac nie rozumiec idei uslug i roznych implementacji.
Klienci to nie mam na mysli firm / ludzi, tylko inne moduly ktore uzywaja moich uslug, nawet w obrebie tej samej aplikacji. Je gowno obchodzi czy tam jest IOException, czy PersistenceException - one reaguja na SaveException, i same moga rzucac cos innego, dajac znac swoim klientom ze cos poszlo nie tak - kolejna abstrakcja, potencjalnie kolejne opakowanie. Zasada jest taka - dana warstwa rzuca swoje wyjatki, zaden wyjatek (poza runtime) nie ma prawa przeciec przez wiecej niz 1 granice miedzy warstwami. Tak jak w stosie protokolow sieciowych - jedna warstwa zna tylko ta pod nia, inne jej nie obchodza, obsluguje jej wyjatki i rzuca swoimi aby dac znac warstwom wyzszym. Wydaje mi sie to zupelnie naturalne, ale mozliwe ze swiat tak szybko sie rozwinal ze to juz nie obowiazuje.
Proble - ktos na koncu lancuszka bedzie logowac wyjatki - i wtedy jest potrzebny caly stack trace, rowniez ten IOException. Jesli kazda warstwa loguje wujatki, pakuje i rzuca dalej, to majac np. 5 warstw, gdzi wyjatek nastapil w tej najnizszej, mamy 5 razy logowane, z czego stos najglebszego wyjatku jest logowany 5 razy, wyjatek z warstwy wyzszej 4 razy, nastepny 3 itp.
Inna mozliwosc to logowac dany wyjatek, rzucac jakis inny z jakimis tak informacjami kontekstowymi i nie opakowywac tego ktory wszystko zepsul. Wtedy jest problem ze mamy w logach stosy ktore sa ze soba jakby niepolaczone, ale tak naprawde dotycza jednej sytuacji wyjatkowej. Tak zle i tak niedobrze.
Dlatego wlasnie pytam jak Wy to robicie. Uprzejmie prosze jeszcze innych, doswiadczonych programistow, o zdanie.
Misiekd napisał(a)
Znaczy mówimy o gotowym programie, czy o jakimś subsystemie, który potem dalej jest oprogramowywany (ma jakieś swoje API) przez innych programistów? Bo jeśli to drugie to zasady są trochę inne niż w przypadku gotowego programu. W gotowym programie to Ty masz władzę i panowanie nad wszystkim, jeśli natomiast piszesz coś, z czego korzystał będzie ktoś inny przy pomocy jakiegoś API to to API powinno być zunifikowane i na takie same zadania odpowiadać tak samo.
Tylko tutaj weź pod uwagę jedną bardzo ważną rzecz - jeśli ZAWSZE rzucisz SaveException podczas zapisu to ktoś, kto korzysta z Twojej biblioteki nie będzie miał pojęcia co poszło nie tak. W końcu po coś wymyślono konkretne wyjątki zamiast zawsze i wszędzie rzucać po prostu GeneralException czy co tam w javie siedzi na samej górze hierarchii.
Tak, mowie o subsystemie.
Wyjatki ktore definiuje sa na odpowiednim poziomie abstrakcji i granularyzacji (tak sie to mowi?) - SaveException znaczy save exception; jesli jakis subsytem musi cos zapisac aby cos zrobic, a nie moze zapisac, to wyzszej warstwy nie obchodzi czy nie zapisal czy nie, tylo ze nie nie zrobil co mial zrobic.
Taki przyklad - kupujesz bilet na samolot do cioci z Hameryki. Nie udaje ci sie kupic - dostajesz blad 'blad transakcji' czy cos takiego. Nie wiesz czy:
a) serwer bazy danych Lotu, czy moze Mastercard, jest niedostepny
b) nie wiesz czy Lot nie ma neta, a moze nastapil timeout
c) nie wiesz czy Mastercard nie zautoryzowal karty*
Nie obchodzi Cie to! Ty nie mozesz kupic biletu, kropka.
- akurat zdaje sie bledy autoryzacji karty sa pokazywane, ale nie jest to blad ktory idzie sobie od mastercarda, tylko jest opakowany przez system kupna biletow. wiem bo pisalem cos takiego dla wielkiej firmy
Aha, no i tak, chodzi mi o wielka, modularna, wielomodulowa, wielowartwowa (warst jak u cebuli, i jeszcze kilka) aplikacje klasy 'enterprise' (cokolwiek to znaczy). Nie malego okienkowego appsa ktory wyszukuje danych w plikach w danym folderze.