Kiedyś przeczytałem o antypaternie jakim jest tworzenie nowego typu wyjątku, który jest per aktualny projekt, czyli np. GitHubException, ktory dziedziczy z System.Exception i nie dodaje własnych pól ani zachowania. Tworzymy go ponieważ wszystko co już jest nie pasuje nam, a wiadomo, że rzucanie Exception też jest złem. Taki wyjątek nic nie wnosi.
Łatwo powiedzieć, trudniej zakodować. Dlatego niestety ten anty wzorzec ciągle powraca i sam się narzuca.
Kontekstem dla dalszych rozważań nie jest pisanie własnego frameworku, piszemy aplikację dla użytkownika końcowego.
Mam pewien typ (dokładnie BlockData) dostarczany z frameworku z którego korzystamy. Trzeba po nim podziedziczyć i dodać własne zachowanie. Ten typ może działać w dwóch „trybach” w zależności od tego jak go inny programista dalej użył. Mój MyBlock dziedziczyy z BlockData, ale nie może być użyty w jednym z tych trybów (po prostu dalsza logika się wywali).
Tak bym widział rozwiązanie sytuacji:
var content = BlockHelper.TryCastToContent(CurrentBlock); if (content == null) { throw new IDontKnowException(string.Format( "Block '{0}' can only be used as a SHARED block", typeof(MyBlock).Name)); }
Tylko co podstawic za IDontKnowException? Dobry wybór to InvalidOperationException. Wyjątek niedoceniany, często zapominam, że warto go używać. Mówi on, że programista (ten który złapał taki wyjątek) wykonuje coś źle i powinien poprawic swój kod. W odróżnieniu od np. podania złych danych przez użytkownika, czy różnych timeoutów na które programista nie ma wpływu.
Lekcja jest taka, że jeśli czujesz, że trzeba coś rzucić, a nie wiesz co, to spytaj kogoś bardziej doświadczonego, prawdopodobnie jest już istniejący dobry sposób rozwiązania sytuacji.
Pingback: dotnetomaniak.pl