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.

Refactoring Day 17 : Extract Superclass