Los Techies : Blogs about software and anything tech!

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.

Kick It on DotNetKicks.com
Posted Aug 18 2009, 08:30 AM by schambers

Comments

Rob White wrote re: Refactoring Day 18 : Replace exception with conditional
on 08-18-2009 11:34 AM

I think the general idea is sound, but it's worth noting that this kind of code is vulnerable to race conditions, so the exception may still need to be thrown by Motor.Cook(food)

Eyston wrote re: Refactoring Day 18 : Replace exception with conditional
on 08-18-2009 1:24 PM

Maybe it is just a bad example ... but having to check a boolean result seems very c'ish doesn't it?

If I call microwave.Start(food) and the microwave can't do it... is an exception appropriate?  It seems like a message back to the caller on why it can't start would be useful ... but I don't know if an exception is an abuse or not (ie it doesn't seem that exceptional).

Quick Joe Smith wrote re: Refactoring Day 18 : Replace exception with conditional
on 08-20-2009 8:35 AM

Going with the example, it may depend on why the microwave can't start. It may be in use, it may be broken, it may not be plugged in. Returning false isn't going to shed much light on the problem. Sometimes just knowing something failed isn't enough.

Both examples however do just that (return false). Perhaps it is better to combine conditional checking (eg, IsInUse, IsPluggedIn, IsBroken, etc.) with throwing the appropriate exception, enabling calling code to take proper action, such as microwave.PlugIn() or while(microwave.InUse) { Thread.sleep(1000); }.

张荣华 wrote 31天重构指南之十八:使用条件判断代替异常
on 10-13-2009 3:49 AM

今天要说的重构来自于我日常工作中的发现而不是其它的什么地方,我在日常工作中经常使用这个重构,我想针对今天要解决的问题可能还有其它的解决方案。在日常的编码中我们经常需要用到异常来控制程序流,下面的...

31 Days of Refactoring « Vincent Leung's .NET Tech Clips wrote 31 Days of Refactoring « Vincent Leung's .NET Tech Clips
on 10-28-2009 9:28 AM

Pingback from  31 Days of Refactoring « Vincent Leung's .NET Tech Clips

PetterLiu wrote 31 Days of Refactoring
on 11-27-2009 4:01 AM

Refactoring Day 1 : Encapsulate Collection Refactoring Day 2 : Move Method Refactoring Day 3 : Pull ...

PetterLiu wrote 31 Days of Refactoring
on 11-27-2009 4:03 AM

Refactoring Day 1 : Encapsulate Collection Refactoring Day 2 : Move Method Refactoring Day 3 : Pull ...

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems