Lanciare un'eccezione generica come FooServiceException
rende la firma del metodo facile da leggere, ma si presume anche che il chiamante probabilmente non vorrà differenziarsi. Se lo facesse, potrebbe ancora farlo, ma dovrà rubare il codice per scoprire quali implementazioni specifiche di FooServiceException
vengono lanciate. Non fare il chiamante farlo! Ecco perché non possiamo avere cose carine!
D'altra parte, se il tuo metodo getById
sta lanciando FooConnectionTimeoutException, FooConnectionPoolExhaustedException, FooTableNotFoundException, FooServiceObjectNotFoundException
, chiaramente qualcosa non va bene in questo caso. Ma non temere più, mio buon OP! C'è una soluzione.
Puoi organizzare eccezioni per tipo, quindi lanciare un'eccezione ragionevolmente generica per ogni tipo possibile. In altre parole, avere FooConnectionTimeoutException, FooConnectionPoolExhaustedException, FooTableNotFoundException
deriva da FooDatabaseException
. La firma del metodo diventa quindi:
getById(int id) throws FooServiceObjectNotFoundException, FooDatabaseException;
Vedi com'è bello? I chiamanti che desiderano coprire tutte le eccezioni non andrebbero oltre la gestione di solo FooServiceObjectNotFoundException
e FooDatabaseException
. I chiamanti che desiderano eseguire un'azione diversa su FooServiceObjectNotFoundException
non possono farne a meno.
Puoi organizzarti ulteriormente secondo necessità, se vuoi essere più dettagliato, ma il livello di dettaglio dipende interamente da te. Il punto chiave è che hai il pieno controllo su quanto specifici vuoi che siano le tue eccezioni. Come regola generale, prova a ridurre il numero di eccezioni generate a 3 o meno. Qualunque cosa al di là di questo è in qualche modo inutile, specialmente se molte delle eccezioni sono correlate allo stesso tipo di problema (problemi imprevisti, errori di business, input non validi, ecc.).