如何有效地初始化装饰器集合?

时间:2014-10-16 16:08:39

标签: ruby-on-rails ruby design-patterns

给定DB结果集,我想有效地装饰它的所有项目。

这是我目前的做法:

@results = MyModel.all.map { |object| MyModelDecorator.new(object) }

我在控制器中一直这样做,所以我必须迭代所有项目来装饰它们,每次都实例化装饰器类。

然后在模板中我再次迭代结果以显示它们。所以我做了两次迭代。

这有效还是有更好的方法呢?

2 个答案:

答案 0 :(得分:1)

您可以介绍一种简化方法来简化事情。

# In the model...

class MyModel
  def decorated
    MyModelDecorator.new self
  end
end

# In the controllers...

@decorated_results = MyModel.all.map &:decorated

# In the views...

for decorated_model in @decorated_results
  <%= decorated_model.data %>
end

您也不应该遍历结果集两次。消除上述调用,并在您真正需要时装饰东西:

# In the controllers...

@results = MyModel.all

# In the views...

for model in @results
  <%= model.decorated.data %>
end

另外,尝试确定是否确实需要在结果集中装饰每个元素。每次你这样做,你都会创造另一个对象;从性能的角度来分配内存和其他这样烦人的东西。您创建的对象越少越好。

此外,对于大结果集,operate in batches

答案 1 :(得分:0)

  

这有效还是有更好的方法呢?

要确定成本,您需要两个数据。

  1. 装饰者构造函数的成本
  2. 模型实例的数量
  3. 大多数装饰器都是简单的ruby对象,因此具有廉价的构造函数。

    Ruby可以每秒实例化数百万个对象:

    require 'benchmark'
    puts Benchmark.measure { 1_000_000.times do Object.new end }
    #=>   0.180000   0.000000   0.180000 (  0.179265)