【发布时间】:2015-06-18 18:15:18
【问题描述】:
我最近遇到 Replace Conditional with Polymorphism Refactoring,同时要求消除 ruby 中的 if..else 条件。the link
谁能告诉我如何在 ruby 中实现相同的功能?(一个简单的代码就可以了)
【问题讨论】:
标签: ruby
我最近遇到 Replace Conditional with Polymorphism Refactoring,同时要求消除 ruby 中的 if..else 条件。the link
谁能告诉我如何在 ruby 中实现相同的功能?(一个简单的代码就可以了)
【问题讨论】:
标签: ruby
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 的子类再次将重构应用到NorwegianBlue#speed:
class NorwegianBlue
def speed
base_speed(@voltage)
end
end
class NailedNorwegianBlue < NorwegianBlue
def speed
0
end
end
瞧,你所有的条件都消失了。
您可能会问自己:这总是有效吗?我可以总是将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
【讨论】:
speed(norwegian_blue) 您将如何使用您的代码实现相同的功能?
speed 方法是 NorwegianBlue 类的方法,就像我在重构示例中展示的那样,就像在重构书和我链接到的重构网站上解释的那样。
我想我会稍微不同地格式化粗体短语,即:重构代码以用多态替换条件。
如果这确实是评论的意思,那么 Yehuda Katz 有一篇很棒的帖子,用 ruby 给出了一个例子: http://yehudakatz.com/2009/10/04/emulating-smalltalks-conditionals-in-ruby/
基本上,参数是存在 if/else 语句以根据布尔值执行不同的代码。它需要特殊的语法,并且仅限于 TrueClass/FalseClass 类型(或 Object/NilClass,如果您对真实性松懈的话)。另一方面,动态调度执行相同的操作,即根据对象的值选择要执行的代码分支,但它不依赖于专门的语法,也不限于任何特定的类型组。
【讨论】: