Rails源代码 - 为什么要在类中包装类?

时间:2016-12-11 12:27:32

标签: ruby-on-rails ruby

我正在阅读rails源代码,我可以在一些代码中看到,而不是直接使用该类,它创建了一个子类。示例代码:

# activesupport/lib/active_support/execution_wrapper.rb
class RunHook < Struct.new(:hook) # :nodoc:
  def before(target)
    hook_state = target.send(:hook_state)
    hook_state[hook] = hook.run
  end
end


# railties/lib/rails/application.rb
def initialize
  # some code..
  @executor          = Class.new(ActiveSupport::Executor)
  @reloader          = Class.new(ActiveSupport::Reloader)
  # some more code
end

我的问题是..为什么需要使用子类?为什么不直接使用class / struct?

感谢。

更新:我已经找到了第二个例子的原因,因为ActiveSupport::Executor定义了inherited方法:

class << self # :nodoc:
  attr_accessor :active
end

def self.inherited(other) # :nodoc:
  super
  other.active = Concurrent::Hash.new
end

所以无论谁扩展课程,都会使用新的active定义Concurrent::Hash属性。

但是,我仍然不太明白为什么Struct需要延长。

1 个答案:

答案 0 :(得分:0)

因为它对性能及其逻辑上的不同类型有影响。 RunHook具有扩展功能。在使用基本def before(target)的所有情况下,无需致电Struct。因此,这里编写了一个具有特定方法的新类,该类将用于需要此方法的特定情况。基本Struct可用于所有其他一般情况,其中不需要具有附加功能的特定类型。

这也是关于安排代码的架构和设计问题。如果代码在类之间正确分割,则更容易维护程序。 面向对象编程和设计有五个基本原则:SOLID。根据{{​​3}}原则:&#34;许多特定于客户端的接口优于一个通用接口&#34;。