什么是多态重构的条件替换?它是如何在Ruby中实现的?

时间:2015-06-18 18:15:19

标签: ruby

我最近遇到了用多态重构替换条件,同时要求在ruby中消除if..else条件。the link

有人可以向我解释我如何在ruby中实现相同的功能?(一个简单的甜蜜代码可以做到)

2 个答案:

答案 0 :(得分:7)

Replace Conditional with Polymorphism Refactoring相当简单,几乎就是它的声音。你有一个像这样的条件的方法:

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

你用这样的多态来替换它:

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

您可以通过创建NorwegianBlue#speed的子类再次将重构应用于NorwegianBlue

class NorwegianBlue
  def speed
    base_speed(@voltage)
  end
end

class NailedNorwegianBlue < NorwegianBlue
  def speed
    0
  end
end

Voilà,你所有的条件都消失了。

您可能会问自己:总是有效吗?我可以总是用消息发送替换if吗?答案是:yes, you can!事实上,如果你没有if,你可以自己实现它,只使用消息发送。 (事实上​​,这就是Smalltalk如何做到的,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

同样相关:Anti-IF Campaign

答案 1 :(得分:1)

我想我会粗略地对粗体短语进行格式化,即:重构代码以用多态来替换条件。

如果这确实是评论的意思,那么Yehuda Katz在ruby中有一个很好的帖子给出一个例子: http://yehudakatz.com/2009/10/04/emulating-smalltalks-conditionals-in-ruby/

基本上,参数是存在if / else语句,以根据布尔值执行不同的代码。它需要特殊的语法,并且仅限于TrueClass / FalseClass类型(如果你对真实性松懈,则仅限于Object / NilClass)。另一方面,动态分派执行选择基于对象值执行的代码分支的相同操作,但它不依赖于专用语法,也不限于任何特定类型的组。