ruby-on-rails - Rails 源代码 - 为什么将类包装在类中?

标签 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

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

谢谢。

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

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

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

因此无论谁扩展类,都将具有使用新的 Concurrent::Hash 定义的 active 属性。

不过,我还是不太明白为什么Struct需要扩展。

最佳答案

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

这也是一个关于安排代码的架构和设计问题。如果代码在类之间正确拆分,则程序更容易维护。 面向对象编程和设计有五个基本原则:SOLID .根据ISP原则:“许多特定于客户端的接口(interface)优于一个通用接口(interface)”。

关于ruby-on-rails - Rails 源代码 - 为什么将类包装在类中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41086151/

相关文章:

sql - 是否可以使用范围方法生成 SQL `OR` 子句?

ruby-on-rails - 在 Rails3 中选择每天的平均不同值

ruby-on-rails - 通过命令行附加 Rails/Paperclip

ruby - Chef Ohai : how to use newly installed Ruby with gem_package

ruby-on-rails - 在远程服务器上执行 rake 任务

ruby-on-rails - 尝试将 Heroku 数据库下载到本地 : Connection to Database Failed

ruby - 如何在 Ruby 中正确使用 ljust 和 rjust?

ruby - 使用 Chef 角色插入属性

ruby - 是否可以从 Ruby 中的外部文件加载正则表达式?

Ruby - 如果乘以等于第三个数字,则查找数组中是否有任何两个数字