Wednesday, January 27, 2010

Refactoring switch-code to objects, howto

Recently, I had an opportunity to suggest a refactoring of some switch-code (case-like statements) into objects. So... if the original source (in Ruby) were:

case condition_variable
when :condition_one
  # This condition requires the most lines to handle, let us say.
  <code for handling condition one>
when :condition_two
  <code>
when :condition_three
  <code>
end #case

The first increment of refactoring is as follows. See how it cleanly divides and documents the code for handling condition one? (An important part of refactoring-to-patterns is stopping when the ugliness no longer shouts!)

class ConditionOne
  def handle( <parameters for handling condition one> )
    <code for handling condition one>
  end #def
end #class
case condition_variable
when :condition_one
  ConditionOne.new().handle( <arguments>)
when :condition_two
  <code>
when :condition_three
  <code>
end #case

If later a need is felt to refactor conditions two and three, another increment of refactoring is:

condition = case condition_variable
when :condition_one
  ConditionOne.new( <arguments for condition one>)
when :condition_two
  ConditionTwo.new( <arguments for condition two>)
when :condition_three
  ConditionThree.new( <arguments for condition three>)
end #case
condition.handle()

Some further refactoring leads to:

i = [ :condition_one,
    :condition_two,
    :condition_three].
    index( condition_variable)
arguments = [ # For condition...
    [<arguments>], # one.
    [<arguments>], # two.
    [<arguments>]] # three.
condition = [
    ConditionOne,
    ConditionTwo,
    ConditionThree].at( i).new( arguments.at( i))
condition.handle()

If a need is felt, further refactoring could subclass a class called, Condition.

Actually, ConditionOne and its siblings want meaningful, specific names. See how this solves the problem of the code being too procedural?

Sources & further information:
AnalysisIsRefactoring
CaseStatementsConsideredHarmful
HistoryOfRefactoring
PolymorphismVsSelectionIdiom
RefactoringIsaRequirement
RefactoringToPatterns
RefactorLowHangingFruit
RefactorMercilessly
SafelyRefactoringLegacyCode
SwitchStatement
SwitchStatementsSmell
WhatIsaFactor
WhyDidYouRefactorThat
WhyNotEnoughRefactoringHappens

Copyright (c) 2010 Mark D. Blackwell.

No comments:

Post a Comment

Thanks for commenting on my post!