2014-12-26 167 views
1

這是我在我的Ruby on Rails應用程序中使用的bmr計算的假實現。如何擺脫if語句

由於該公式僅使用公制單位,因此如果將英制單位設置爲用戶的默認單位,則必須以某種方式將英制單位轉換爲公制。

我想出了這段代碼。

我個人認爲這種小問題有很多代碼。從這個角度來說,使用多態性將超過工程。 改進此代碼的方法?

require 'ostruct' 
require 'delegate' 

module BmrCalculator 
    class Calculator 
    def call(sex = :male, measurement_unit = :metric) 
     user = OpenStruct.new(sex: sex, weight: 2, height: 2, measurement_unit: measurement_unit) 

     if measurement_unit == :imperial #dont like it 
     user = ImperialToMetricDecorator.new(user) 
     end 

     BmrCalculator.new.bmr(user) 
    end 

    class BmrCalculator 
     def bmr(user) 
     if user.sex == :male 
      puts user.inspect 
      puts 1 * user.weight + 2 * user.height + 3 #this formula works only with metric units 
     else 
      puts user.inspect 
      puts 6 * user.weight + 3 * user.height + 5 #this formula works only with metric units 
     end 
     end 
    end 
    end 

    class ImperialToMetricDecorator < SimpleDelegator 
    def height 
     (super * 2.54) 
    end 

    def weight 
     (super/2.2) 
    end 
    end 

    Calculator.new.call(:male, :metric) 
end 
+0

直到你「受到」if語句,我不會說他們肯定是壞的。多態性的好處之一就是當你需要添加第三/第四/第五種情況時。對於男性和女性來說,幾乎可以保證你不會。另一方面,如果您發現由於新的要求而更改if語句會變得很痛苦,那麼請進行設計更改,以使其更容易。 – Fuhrmanator

回答

3

您可以通過使用OOP和創造有意義的交涉提高代碼:

class Length < Float 
end 

class Feet < Length 
    def to_meters 
    .. 
    end 
end 

class Meters < Length 
    def to_feet 
    .. 
    end 
end 

class Gender < Object 
end 

class Male < Gender 
    def bmr(weight) 
    ... 
    end 
end 


class Female < Gender 
    def bmr(weight) 
    ... 
    end 
end 

這可能看起來像一個更多的代碼,但它實際上是更容易閱讀,測試和維護。