【问题标题】:Ruby style question : blocks or inheritance?Ruby 风格问题:块还是继承?
【发布时间】:2009-01-13 22:21:23
【问题描述】:

我有一些类会根据某些条件做某事。条件作为参数发送给某些方法。我的问题与 ruby​​ 编码风格有关:

  • 条件应该作为 lambdas/blocks 发送,还是作为从条件类继承的某些对象发送?

  • 在 OOP 方面哪个更高效?

谢谢!

【问题讨论】:

  • 总是先问,“什么对人类最有效?”只有当机器没有这种方式的资源时,你才应该问,“什么对机器更有效?”

标签: ruby oop coding-style


【解决方案1】:

我不知道从执行时间的角度来看哪个更有效,但从用户界面的角度来看,块更有效。使用您的方法的人只需将条件写入一个块中,而不必定义一个全新的类、创建一个实例并将其传递给您的方法。

【讨论】:

  • 大型项目怎么样?长期项目?
  • 在大型项目中为自己节省时间和编写样板代码更为重要。
【解决方案2】:

这一切都可以忽略不计,这取决于您实际在做什么以及是否可以缓存条件对象或过程,但通常块是 Ruby 方式,它们比对象创建更快。

这是一个无用的基准:

require 'benchmark'

# Useless parent class
class Condition; end

# Useless inheritance.  Duck typing FTW.
class AddCondition < Condition  
  def call
    1 + 1
  end
end

def with_object(condition)
  condition.call
end

def with_block
  yield
end

n = 100000
Benchmark.bm(10) do |x|
  x.report("object:") do
    n.times do; with_object(AddCondition.new); end
  end
  x.report("block:") do
    n.times do; with_block { 1 + 1 };          end
  end
end

结果:

                user     system      total        real
object:     0.090000   0.000000   0.090000 (  0.087227)
block:      0.060000   0.000000   0.060000 (  0.063736)

【讨论】:

  • 我们可以解释一下,因为创建一个对象比将两个值相加更昂贵。
  • @Donovan,这不仅仅是将两个值相加;该块也被创建。保持对 closure 使用的堆栈的引用仍然存在开销。
  • ...但是是的,创建对象的成本更高。
【解决方案3】:

Lambda 更像是 Ruby 的方式——除此之外,为什么要为一个简单的 lambda 就可以的东西定义一个完整的大类?或者,您可以像 Rails 那样传递条件。

【讨论】:

  • 如果我需要设置多个条件的课程怎么办?我将在哪里存储所有条件?一个名称空间包含一个散列和一大堆条件作为散列值?
  • 除了它“会根据某些条件做某事”之外,您没有提供有关程序结构的任何信息,所以我不知道您将任何内容存储在哪里。
【解决方案4】:

在这种情况下我会使用继承的唯一情况是,如果条件本身使用许多通用代码,可以在超类中完全实现(无需覆盖子类中的任何内容),但是在 Ruby 中不常用继承 Java 风格接口的做法。

无论如何,您正在做的事情被称为控制和策略模式的倒置,请阅读相关信息以获取更多信息。关键是让代码的用户决定代码的最终行为是(好的)决定,而不是配置参数或实现中的某种其他类型的分支。

【讨论】:

    猜你喜欢
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2017-12-09
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    相关资源
    最近更新 更多