我正在阅读 Rails AntiPatterns书,我很喜欢。在某一时刻,作者谈到了组合的优点,并给出了一个示例,其中 Order 类将转换(到其他格式)的责任交给另一个类,称为 OrderConverter>。这些类定义为:
class Order < ActiveRecord::Base
def converter
OrderConverter.new(self)
end
end
class OrderConverter
attr_reader :order
def initialize(order)
@order = order
end
def to_xml
# ...
end
def to_json
# ...
end
...
end
然后作者说:“通过这种方式,您可以在一个单独且易于测试的类中为转换方法提供自己的家。导出订单的 PDF 版本现在只需调用即可以下内容:”
@order.converter.to_pdf
对此,我的问题是:
为什么你认为订单对象前面有一个@?它不应该被创建为:
order = Order.new
然后通过执行以下操作进行转换:
order.converter.to_pdf
- 为什么 OrderConverter 中需要
attr_reader :order
行?这样我们就可以从 OrderConverter 对象访问订单?是否需要能够做到order.converter.to_pdf
?如果没有 attr_reader,我们也可以做到这一点,对吗?
最佳答案
Order
的实例被传递给 initialize
方法并存储为实例变量(使用 @ 语法:@order
)。这样,就可以从转换器中的其他方法访问该变量(该变量具有实例范围):
class OrderConverter
def to_pdf
@order.items.each do |item|
# Write the order items to the PDF
end
end
end
attr_reader 不是严格必需的,但它是从其他方法访问 Order 对象的便捷方法:
class OrderConverter
def to_pdf
order.items.each do |item|
# Write the order items to the PDF
end
end
end
它还允许您从任何转换器实例中获取对订单的引用:
converter.order
关于ruby-on-rails - Rails AntiPatterns 书 - 对组合的质疑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9000617/