2017-07-05 96 views
0

我已经使用Reek最近重构我的代码和气味中的一个,DuplicateMethodCall,被称为上数组和散列查找,如array[1]hash[:key]时称为多次。如果多个阵列/哈希查询被存储在一个变量

所以我在想,如果有多个数组或哈希查找是如此昂贵,我们应该在一个变量来存储它们,而不是直接调用它们,这是每个人都从我的经验呢。

我会毫不犹豫地存储多个对象方法调用(尤其是如果它是一个DB调用)在一个变量,但这样做对于数组和哈希查找感觉就像矫枉过正。

例如,我会得到一个警告,对这段代码:

def sort_params 
    return [] if params[:reference_letter_section].nil? 

    params[:reference_letter_section].map.with_index(1) do |id, index| 
     { id: id, position: index } 
    end 
    end 

,但我觉得在自己的变量存储params[:reference_letter_section]太多

+0

代码质量的工具应经常采取一粒盐。当性能不是问题时,可读性很重要。但用你的判断来决定哪种方式更好。这些工具只是告诉你在哪里看。 – ndn

+0

呀完全与它@ndn同意,但我不知道有多少,它会提高性能,这就是为什么我问这个位置 –

+1

“我不知道有多少,它会提高性能” - 你可以随时_measure_那。 –

回答

2

所以我在想,如果多个阵列或哈希查询是如此昂贵

昂贵的电话不是多次不打电话的唯一原因。它也混淆了代码而没有真正的需要。考虑一下这个不那么做作例如:

Order.new(
    name:  params[:order][:name], 
    total:  params[:order][:total], 
    line_items: [ 
    { 
     product_name: params[:order][:line_item][:product], 
     price:  params[:order][:line_item][:price], 
    } 
    ] 
) 

即使这些散列访问是超级便宜,但它仍然是有意义的提取它们,可读性原因。

order_params  = params[:order] 
line_item_params = order_params[:line_item] 

Order.new(
    name:  order_params[:name], 
    total:  order_params[:total], 
    line_items: [ 
    { 
     product_name: line_item_params[:product], 
     price:  line_item_params[:price], 
    } 
    ] 
) 
+0

当然,我并不意味着这是唯一的原因。但是,当可读性不吃亏,而只是增加了行数,我在想,如果它仍然是值得的 –

+0

@MaximFedotov:好,这是一个主观判断。不应该盲目信任这些工具。他们不知道什么是好的代码。 :) –

+0

是啊,我明白了,但是这正是为什么我张贴的问题,看看有什么经验丰富的开发人员会考虑接受。既然它看起来不会影响性能,我可能会忽略数组/散列,除非它经常被调用。将不得不考虑的更新我的配置 –

0

重复散列查找代表这两行代码之间的耦合。这会增加理解代码的时间,并且在更改代码时可能会产生摩擦。当然,在像这样的小方法中,成本相对较低;但是如果两行代码进一步分开 - 例如在不同的类中,耦合的效果将会更加昂贵。

这是你的方法的版本不具有复制:

def sort_params 
    reference_letters = params[:reference_letter_section] || [] 
    reference_letters.map.with_index(1) do |id, index| 
    { id: id, position: index } 
    end 
end