【问题标题】:Class vs Module in designing Ruby API?设计 Ruby API 中的类与模块?
【发布时间】:2010-11-02 04:41:53
【问题描述】:

当我阅读更多关于 Ruby 元编程的内容时,大多数时候我们发现至少有两种解决方案可以解决一个问题。请看下面两个例子:

class Base
  def self.has_many(*args)
    # ...
  end
end

class Student < Base
  has_many :books
end

另一种风格:

module Base
  def self.included(klass)
    klass.extend ClassMethods
  end

  module ClassMethods
    def has_many(*args)
      # ...
    end
  end
end

class Student
  include Base

  has_many :books
end

但是当我们设计 api 时,我们必须决定使用哪一个,但我想问问你的想法和大多数人已经在他们的库中实现的一些最佳实践。

【问题讨论】:

    标签: ruby api design-patterns inheritance composition


    【解决方案1】:

    如果您的 API 提供将由客户端扩展的基本功能,那么您应该更喜欢继承

    如果您的 API 要用自己的基本功能扩展各种客户端,那么您应该选择 composition

    【讨论】:

      【解决方案2】:

      你有很多关于这个问题的理论。

      我倾向于更喜欢组合,因为这样可以使行为更加可重用,但是如果您查看 Rails,则每次您想要数据库中的对象时都必须继承 ActiveRecord::Base 类。如果您查看 DataMapper,情况正好相反,因为他们只要求您包含 DataMapper::Resource。

      继承与组合(通过模块)是一个大话题,您必须问自己的问题将归结为:如何在我提供的组件与另一个用户现有代码库之间实现更大的解耦?

      【讨论】:

        【解决方案3】:

        Ruby 仅支持单一继承。因此,如果 API 客户端必须继承您的基类,他们将失去继承其他类的能力。使用模块包含,您可以编写如下代码:

        class Student < Person
          include Base
          has_many :books
        end
        

        因此您可以“继承” Person 和 Base。

        不过,经典的继承语法看起来更自然,没有那么“神奇”

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多