sobota, 23 lipca 2011

Własne wyjątki - a na co mi to?


O tym, czym są wyjątki można przeczytać w wikipedii lub na php.net. Ogólnie rzecz biorąc wyjątki powinny być wyrzucane wtedy, gdy w jakiś sposób nasza aplikacja podejmie próbę wykonania niedozwolonej operacji lub nie będzie w stanie wykonać operacji.
Od wersji 5 PHP jest dostarczany z bardzo ciekawą biblioteką SPL, która narzuca pewną hierarchię wyjątków i dzieli je na dwie główne grupy:
  • RuntimeException - są to wyjątki, które powinny być wyrzucane, gdy aplikacja z pewnych względów nie może poprawnie działać np. zerwanie połączenia z bazą danych.
  • LogicException - są to wyjątki, które powinny być wyrzucane, gdy aplikacja próbuje wykonać operacje, które są błędne np. wywołanie nieistniejącej metody na przekazanym obiekcie.
Szerszy opis wszystkich wyjątków, które są dostarczone wraz z biblioteką SPL znajdziecie tutaj.

Dobra, po trochę przydługim wstępie, wracam do głównego wątku:) A więc po co tworzyć własne wyjątki? Przecież można z łatwości wpisać odpowiedni message do konstruktora tego bazowego (Exception) i po sprawie. Oczywiście, że tak można, ale tylko do momentu, gdy wyjątki są rzeczywiście tylko i wyłącznie kontenerem na jakąś informację.

Oczywiście powodów stosowanie wyjątków jest kilka, ja jednak pozwolę sobie skupić się na, moim zdaniem najważniejszym, czyli utrzymywaniem spójnej logiki tzn. jeżeli mam klasę Product, Product_Factory, Product_Collection etc. to dobrze jest mieć jeszcze Product_Exception, który będzie wykorzystywany w tych właśnie klasach i tylko w tych. Dzięki temu już po samym typie wyjątku wiem, gdzie się wysypała aplikacja, a do dokładniejszego określenia miejsca załamania powinno się wykorzystywać wartość $message.
Oczywiście można tutaj popaść w pewną skrajność i zacząć tworzyć wyjątki dla wszystkiego i tak dostajemy: Product_Exception, Product_Factory_Exception, Product_Collection_Exception etc., gdzie każdy wyjątek jest wyrzucany jeden, no góra dwa razy w całym kodzie. I po co to? Niestety jest to częsta przypadłość programistów, którzy dopiero odkryli tą cudowną możliwość dziedziczenia po klasie Exception - po prostu zapominają o tym, że wyjątek posiada jeszcze argument $message.

Niestety złotego środka nie ma i już we własnym zakresie trzeba zdecydować, czy to już powinien być kolejny typ wyjątku, czy jeszcze ten sam, z odpowiednią wiadomością. Granica jest płynna, ważne jest to, aby pamiętać o dwóch rzeczach:
  • Dziedziczyć po klasie Exception jest w PHP dozwolone.
  • Konstruktor klasy Exception posiada możliwość przyjmowania parametrów m.in. $message i $code.