Refactoring Day 18 : Replace exception with conditional
Today’s refactoring doesn’t come from any place specifically, just something I’ve picked up over time that I find myself using often. Any variations/comments would be appreciated to this approach. I think there’s some other good refactorings around these type of problems.
A common code smell that I come across from time to time is using exceptions to control program flow. You may see something to this effect:
1: public class Microwave
2: {
3: private IMicrowaveMotor Motor { get; set;}
4:
5: public bool Start(object food)
6: {
7: bool foodCooked = false;
8: try
9: {
10: Motor.Cook(food);
11: foodCooked = true;
12: }
13: catch(InUseException)
14: {
15: foodcooked = false;
16: }
17:
18: return foodCooked;
19: }
20: }
Exceptions should only be there to do exactly what they are for, handle exceptional behavior. Most of the time you can replace this type of code with a proper conditional and handle it properly. This is called design by contract in the after example because we are ensuring a specific state of the Motor class before performing the necessary work instead of letting an exception handle it.
1: public class Microwave
2: {
3: private IMicrowaveMotor Motor { get; set; }
4:
5: public bool Start(object food)
6: {
7: if (Motor.IsInUse)
8: return false;
9:
10: Motor.Cook(food);
11:
12: return true;
13: }
14: }
This is part of the 31 Days of Refactoring series. For a full list of Refactorings please see the original introductory post.