An alternative to throwing exceptions, possibly an AntiPattern.
The idea is to just bury the code to handle exceptional cases in the object that does the normal action. This is much simpler than using exceptions or some other mechanism, but very difficult to test, breaks the OneResponsibilityRule, is low on communication, and so on.
ExceptionHandlingChallenge entry:
UserDatabase.add(user);
mailPassword(email, password);
redirect("success");
(That is, when an exception occurs, you have the U
serDatabase.add() and mailPassword() methods themselves do the database-recovery and redirection.)
Pros:
Cons:
- Where do you put the UserDatabase?.delete(email)? Hopefully not in mailPassword()! (cf: YouDontWantAnExceptionYouWantaTimeMachine)
- Breaks the OneResponsibilityRule - A UserDatabase? shouldn't be responsible for redirection.
- Tightly couples classes to the redirection code, which has these bad effects:
- Difficult to UnitTest. You might have to use the PassErrorHandler? version just for the tests.
- If you want to handle the error differently, you're going to have to refactor to one of the above (probably the PassErrorHandler? version). But, who cares, since YouArentGonnaNeedIt.
- The reader never knows how exceptional cases are handled.
- I guess you could have 'UserDatabase.add' set a flag or add a "rollback object" to a hidden global stack somewhere. Then mailPassword could check the global flag, to see if it should do its work, or just exit without doing anything. And mailPassword, on failure, could traverse the global stack, calling all "undo" methods. Ick!!! This coupling is getting out of hand.
CategoryException