What replaces conditionally with polymorphism refactoring? How is this implemented in Ruby?

I recently came across Replace Conditional with polymorphism refactoring asking for a if..else

conditional exception in ruby. link p>

Can someone explain to me how I can implement the same thing in ruby? (Simple sweet code will do)

+3


source to share


2 answers


"Replace conditional with polymorphism refactoring" is pretty straightforward, and pretty much what it sounds like. You have a method with a conditional expression:

def speed
  case @type
  when :european       then base_speed
  when :african        then base_speed - load_factor * @number_of_coconuts
  when :norwegian_blue then if nailed? then 0 else base_speed(@voltage) end
end

      

and you replace it with polymorphism like this:

class European
  def speed
    base_speed
  end
end

class African
  def speed
    base_speed - load_factor * @number_coconuts
  end
end

class NorwegianBlue
  def speed
    if nailed? then 0 else base_speed(@voltage)
  end
end

      

You can apply Refactoring to again by NorwegianBlue#speed

subclassing NorwegianBlue

:



class NorwegianBlue
  def speed
    base_speed(@voltage)
  end
end

class NailedNorwegianBlue < NorwegianBlue
  def speed
    0
  end
end

      

Voilà, all your conventions are gone.

You may be asking yourself: does this always work? Can I always replace a message if

with send messages? And the answer is yes you can ! In fact, if you didn't have one if

, you can implement it yourself using only posting. (This is essentially how Smalltalk does it; there is no convention in Smalltalk.)

class TrueClass
  def iff(thn:, els: ->{})
    thn.()
  end

  def &
    yield
  end

  def |
    self
  end

  def !
    false
  end
end

class FalseClass
  def iff(thn:, els: ->{})
    els.()
  end

  def &
    self
  end

  def |
    yield
  end

  def !
    true
  end
end

(3 > 4).iff(thn: ->{ 'three is bigger than four' }, els: ->{ 'four is bigger than three' } )
# => 'four is bigger than three'

true.& { puts 'Hello' }
# Hello

true.| { puts 'Hello' }
# => true

      

Also relevant: Anti- if

Campaign

+7


source


I think I would format the highlighted phrase slightly differently, i.e.: Refactor your code to replace conditional polymorphism.

If this is indeed what this comment should mean, then Yehuda Katz has a great article giving an example in ruby: http://yehudakatz.com/2009/10/04/emulating-smalltalks-conditionals-in-ruby/



Basically, the argument is that there is an if / else statement to execute other code based on the boolean value. It requires special syntax and is limited to TrueClass / FalseClass types (or Object / NilClass if you're faint about truthfulness). Dynamic dispatch, on the other hand, performs the same operation of selecting branches of code to execute based on the value of an object, but does not rely on specialized syntax and is not limited to any particular group of types.

+1


source







All Articles