在这里使用 attr_accessor 是否更好?

Is it better practice to use an attr_accessor here or not?

我有一个 class QuestionList 存储 'Question' 个对象的列表。

class QuestionList

    attr_accessor :questions

    def initialize
        @questions = []
    end

end

然后我将问题添加到列表中,然后 "ask" 这些来自我的主要 class 的问题如下:

list = QuestionList.new
list.questions << Question.new(5, 3)
list.questions << Question.new(1, 5)
list.questions << Question.new(2, 4)

list.questions.each do |question|
    puts "#{question.ask}"
end

其中 Question.ask 只是将问题输出为字符串。

我不确定使用 << 运算符从我的主 class 写入实例变量是否可以接受,而 list.questions.push(Question.new(5, 3)) 更不清楚主要class。

有一个QuestionsList.add_question(question)方法会更好吗?

list.questions.each 也是如此 - 这是否可以在主要 class 中使用?

我认为您在此处使用 attr_accessor 很好,但根据您继续添加的功能量,将 class 的功能限制为 [=27] 可能会更清楚=]本身。

关于您关于在 QuestionList 中使用方法的问题,这归结为可读性。但是,首先要注意的是:您使用 QuestionsList.add_question(question) 作为示例。这将创建一个 class 方法。您在这里真正需要的是一个实例方法,读作 list.add_question(question),因为您已经创建了列表的实例。 This blog post 有一些关于 class 和实例方法之间区别的有用信息。

我个人认为实例方法最能清楚地传达您的意图。我会写出 QuestionList 如下:

class QuestionList

  def initialize
    @questions = []
  end

  def add_question(question)
    @questions << question
  end

  def print_all_questions_in_list
    @questions.each do |question|
      puts "#{question.ask}"
    end
  end

end

This SO post 有一些关于 Ruby 的 attr 方法的极好的信息,如果你想在那里获得更多信息。

@questions 数组是您的 class 的私有内部实现细节。它应该永远不会 暴露给客户。这有很多原因,两个例子是:

  • 您过度承诺接口:现在,您所有的客户都依赖于它是一个数组。如果您以后想将其更改为其他内容怎么办?文本文件?数据库?网络服务?
  • 您公开了破坏对象不变量的操作:例如,客户端可以向该数组添加一个整数。或者 nil。或任何其他不是 Question.
  • 的东西

如何 你存储你的问题应该是一个实现细节。 QuestionList 应该有管理问题列表的方法。它可能应该有一个 each 方法(和 include Enumerable)和一个 add 方法(可能是 << 的别名)。如果有意义的话,也可能是 []。如果方便的话,这些方法可以简单地委托给数组,但要点是:如果你以后决定不使用数组,你可以在没有人注意到的情况下这样做。您可以决定只支持那些您实际上 想要 支持的方法,而不是 Array.

的所有 ~100 种方法