在这里使用 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 种方法
我有一个 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
.