Friday, February 18, 2011

Switch vs Strategy

Switch vs Strategy:

Recently, I’ve been working with the blend mode feature for Bunnyhill, my upcoming 2D rending engine based on Molehill. And I’ve used strategy objects to replace what could have been written in a switch statement. I think this could be a nice example for replacing switch statements with strategies, so I’ll share some of the details here.

The Switch Appraoch

First let’s take a look at the naive switch appraoch to set the blend mode of a render engine. Say we have a render engine that implements the interface below.

interface IRenderEngine {
 function setBlendMode(value:String):void;
}

And the BlendMode class provides static constants representing different blend modes.

class BlendMode {
 public static const ADD:String = "add";
 public static const ALPHA:String = "alpha";
 public static const NORMAL:String = "normal";
}

A possible render engine implementation for the switch approach is shown below.

class RenderEngine implements IRenderEngine {
 public function setBlendMode(value:String):void {
  switch (value) {
   case BlendMode.ADD:
    //use add blend mode
    break;
   case BlendMode.ALPHA:
    //use alpha blend mode
    break;
   case BlendMode.NORMAL:
    //use normal blend mode
    break;
  }
 }
}

In our main program, we could set the blend mode of the render engine like this.

renderEngine.blendMode = BlendMode.ADD;

The use of switch seems quite reasonable at the first glance, but is identified as “coding bad smell” in Refactoring, by Martin Fowler. If we were to add more blend modes to the render engine, this means we have to add an extra constant in the BlendMode class and an extra case in the switch statement. One feature change results in changes in two places, no good!

This is when the use of strategy objects should be considered.

The Strategy Approach

[...]

No comments:

Post a Comment