2016-02-08 74 views
0

我試過閱讀一些關於重構的教程,我正在努力解決條件問題。我不想使用三元運算符,但也許應該用一種方法提取它?或者有一個聰明的方式來使用地圖?ruby​​ - 重構if else語句

detail.stated = if value[:stated].blank? 
        nil 
       elsif value[:stated] == "Incomplete" 
        nil 
       elsif value[:is_ratio] == "true" 
        value[:stated] == "true" 
       else 
        apply_currency_increment_for_save(value[:stated]) 
       end 
+0

這是一個Rails代碼? - 'blank?'由Rails定義,不屬於Ruby –

+0

如果它是零,你想要做什麼?像提出一個錯誤/死亡/退出? – zee

+0

是的,這是軌道 – user3437721

回答

3

,它可以製成大量清潔器由於早期return(和關鍵字參數):

def stated?(stated:, is_ratio: nil, **) 
    return if stated.blank? || stated == "Incomplete" 
    return stated == "true" if is_ratio == "true" 
    apply_currency_increment_for_save(stated) 
end 

然後...

detail.stated = stated?(value) 
1
stated = value[:stated] 
detail.stated = case 
    when stated.blank? || stated == "Incomplete" 
    nil 
    when value[:is_ratio] == "true" 
    value[:stated] == "true" 
    else 
    apply_currency_increment_for_save stated 
end 

發生了什麼事:  時case而不表達式中使用,它成爲一個if ... elsif ... else ... fi.

您可以使用它的結果的文明等同,太,就像if...end

0

移動代碼到apply_currency_increment_for_save 和做:

def apply_currency_increment_for_save(value) 
    return if value.nil? || value == "Incomplete" 
    return "true" if value == "true" 
    # rest of the code. Or move into another function if its too complex 
end       

的邏輯被封裝並且如果移動此邏輯到一個方法需要2行僅

+0

'apply_currency_increment_for_save'的邏輯現在會變得混亂,因爲它比「應用貨幣增量」做得更多,就像它返回「true」時一樣 - 在某種程度上,它會違反單一責任原則(SRP) –

+0

我不同意,因爲責任是從'value'獲取'陳述'。所以你可以將它重命名爲'parse_stated'或類似的東西。或者,正如我所評論的,您可以將其餘的代碼移動到另一個函數中。對於當前的代碼,它也不是很清楚爲什麼一個名爲'apply_currency_increment_for_save'的函數返回一個狀態。主要想法是刪除案例,並將其推到一個函數中,它更易讀 – dgmora

0

我喜歡@喬丹的建議。但是,看起來呼叫並不完整 - 「is_ratio」參數也是從值中選擇的,但未提供。

只是爲了爭論,我會建議你可以更進一步,並提供,它非常狹隘地專注於評估「規定」的價值。這可能看起來很極端,但它符合單一責任的概念(責任在於評估所陳述的「價值」 - 而「細節」對象可能專注於其他事物,而僅僅利用評估)。

它會是這個樣子:

class StatedEvaluator 
    attr_reader :value, :is_ratio 

    def initialize(value = {}) 
    @value = ActiveSupport::StringInquirer.new(value.fetch(:stated, '')) 
    @is_ratio = ActiveSupport::StringInquirer.new(value.fetch(:is_ratio, '')) 
    end 

    def stated 
    return nil if value.blank? || value.Incomplete? 
    return value.true? if is_ratio.true? 
    apply_currency_increment_for_save(value) 
    end 
end 

detail.stated = StatedEvaluator.new(value).stated 

注意,這使得使用Rails的StringInquirer class

+0

「但是,它似乎是不完整的......」這聽起來像你可能不熟悉[關鍵字參數](在Ruby中https://www.google.com/search?q=ruby+keyword+arguments)。方法簽名'def聲明?(說明:,is_ratio:nil)''表示該方法將一個Hash作爲參數,並使用':stated'和':is_ratio'鍵將哈希值從其中提取到局部變量'stated'和'is_ratio '(分別在缺失情況下缺省值爲'nil')。 –

+0

謝謝,喬丹。實際上,我對關鍵字參數很熟悉。我的評論有點偏離。您的示例中可能出現的問題與hash的潛在可能性不僅僅是「陳述」和「is_ratio」有關。對不起,混音。 – AndyV

+0

哦,我明白了。接得好。我已經更新了我的答案。 –