čtvrtek 17. srpna 2006

Deklarovaná runtime výjimka - nejlepší z obou světů?

Princip výjimek na platformě Java je dostatečně známý, ale to vůbec neznamená, že existuje obecný koncept, jak nejlépe navrhnout systém výjimek z hlediska architektury aplikace. Nedávno byl na serveru TheServerSide diskutován koncept deklarované runtime výjimky, tak se na něj v tomto článku podíváme.

Následující informace vycházejí z článku Declared Unchecked Exception: The Best of Both Worlds uveřejněném na blogu Hacking Architect

Známá fakta

  • hierarchie aplikačních výjimek je odvozena pouze z java.lang.RuntimeException tj. všechny výjimky jsou ze své podstaty runtime
  • každá aplikační výjimka resp. metoda, která jí může vyhodit, tuto výjimku nadeklaruje v throws klauzuli
  • běžné runtime výjimky jako java.lang.NullPointerException, které mohou vzniknout obsluhujeme klasickou cestou tj. žádná explicitní deklarace jako v případě aplikačních výjimek
  
public class MyORMException extends RuntimeException { ... }

public class ObjectNotUniqueException extends MyORMException { ... }

... // define other exceptions

public class MyORMSession {

   public void commit() throws ObjectNotUniqueException, 

         DatabaseException, DataSecurityException;

}

Efekt

Pojďme si zrekapitulovat jak se výše zmíněný koncept projeví v kódu.

  • přestože je výjimka nadeklarovaná v throws klazuli, nemusí jí klientský kód ošetřovat, protože je typu runtime
  • případná budoucí změna throws klazule nevynucuje změnu klientského kódu
  • z deklarace metody můžeme určit, které aplikační výjimky mohou nastat, a které bychom mohli ošetřit

Vedlejší efekt

Samozřejmě tento přístup v našem kódě přinese i vedlejší efekt.

  • přicházíme o statickou typovou kontrolu, žádné upozornění kompilátorem či vývojovým prostředím na neošetřenou výjimku
  • musíme poctivě aktualizovat throws klauzule daných metod

I přes nesporné výhody má tento koncept několik vedlejších efektů. Rozhodně si nemyslím, že by bylo vhodné tento koncept použít pro celou hierarchii aplikačních výjimek. Hierarchie deklarovaných runtime výjimek se hodí pro ty části systému u nichž jsou výjimky z povahy systémové, příkladem budiž databázová vrstva. Místo kde se tento koncept nehodí, představuje aplikační logika. Zde mají opodstatnění kontrolované (checked) výjimky, protože aplikační logika může ze svojí podstaty vynucovat přímé zpracování mimořádné situace např. přečerpání limitu při převodu peněz z účtu na účet.

Moje doporučení vzhledem k tomuto konceptu: užívejte pouze s mírou. Budu jedině rád, když se mnou v diskusi pod článkem podělíte o Vaše zkušenosti, pokud jste tento koncept adoptovali.