【问题标题】:Ruby: How to make only one single method in a class public?Ruby:如何只公开一个类中的一个方法?
【发布时间】:2021-10-10 20:49:02
【问题描述】:

每个类中私有与公共 Ruby 方法的讨论都展示了如何将以下所有方法声明为私有(或公共或受保护):

class airplane
  def preflight
  end

  def engine_start
    return unless preflight_complete?
  end

  private

  def preflight_complete?
  end
end

这在大多数情况下都很有效,您将所有公共方法放在顶部,而将所有私有方法放在下面。

我有一个包含三个公共方法和几十个私有方法的大型类。为了开发者的舒适,私有的都以合乎逻辑的方式排序。

现在,我发现我需要公开 2 或 3 个以前的私有方法。我不想把他们拉到顶端,远离他们的上下文邻居。我还发现每次在publicprivate 之间来回翻牌都很笨拙。如果屏幕尺寸将public 标志推到视野之外,这尤其令人讨厌,并且由于我在单独的公共方法之后插入了第二个或第三个新方法无意公开,这并不明显。

那么,有没有一种优雅的方法可以避免来回翻转 public/private 来只公开一个方法?

【问题讨论】:

  • 老实说,您问题的前提可能是这里真正的问题:“我有一个包含三个公共方法的大型类,并且几十个私人的”。具有“几十种”方法的类听起来非常臃肿;违反了Single-Responsibility principle(另见:SOLID principles),并且通常管理起来非常复杂。
  • 当然,您可以内联定义public/private 方法,但从根本上说,在一个类中拥有 40 多个方法无论如何都会导致更大的问题。 例如,也许最好定义一个单独的AirplaneTank 类,它公开一个#full? 公共方法,而不是将所有这些捆绑到一个Airplane God object 中。
  • @TomLord:提取错误的抽象通常比不理会它更糟糕。无论如何,根据我的经验。
  • @SergioTulentsev 我并没有声称在这里知道正确的抽象,因为我所看到的只是 5 个没有实现细节/上下文的方法名称。我只是举一个潜在抽象的例子。但可以肯定的是,一个包含 40 多个方法的怪物类正在尖叫“我需要抽象!”根据我的经验。
  • @TomLord “一个包含 40 多种方法的怪物类在尖叫“我需要抽象!”根据我的经验。” - 我 100% 同意。

标签: ruby class methods private


【解决方案1】:

只需将public(或私有,受保护)放在方法定义的开头即可:

class airplane
  def preflight
  end

  def engine_start
    return unless preflight_complete?
  end

  private

  def preflight_complete?
  end

  public def tanks_full?
  end

  def pilot_authorized?
  end
end

在这种情况下,pilot_authorized? 仍然是私有的,但任何人都可以检查 tanks_full?

【讨论】:

  • 这是一个不错的技巧,当然,但我认为它弊大于利。成为公共 API 一部分的方法是一个足够大的变化,以保证更大的差异足迹(这将导致更高的位置,进入公共部分)。
  • 我完全同意,塞尔吉奥。在我(真实的话)的情况下,它仍然是一种非常“内部”的方法,不需要广告。但是,回调中存在的另一个类需要从不寻常的地方调用它。我可以使用send :tanks_full?,但我更倾向于公开该方法,即使它不值得最高收费。感谢您的观点!
【解决方案2】:

作为替代方案,您可以通过公共包装器发布此方法。

class airplane
  def preflight
  end

  def engine_start
    return unless preflight_complete?
  end

  def tanks_full?
    _tanks_full?
  end

  private

  def preflight_complete?
  end

  def _tanks_full?
  end

  def pilot_authorized?
  end
end

这样,您的代码仍然清晰地分为两部分,没有任何意外的叛逃者,并且该方法仍然靠近其上下文邻居。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多