Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何摆脱if语句_Ruby On Rails_Ruby_Design Patterns_Polymorphism_Decorator - Fatal编程技术网

Ruby on rails 如何摆脱if语句

Ruby on rails 如何摆脱if语句,ruby-on-rails,ruby,design-patterns,polymorphism,decorator,Ruby On Rails,Ruby,Design Patterns,Polymorphism,Decorator,这是我在RubyonRails应用程序中使用的计算的一个伪实现 由于公式仅使用公制单位,如果用户将英制单位设置为默认单位,我必须以某种方式将英制单位转换为公制单位 我已经想出了这个密码 我个人认为,对于这种小问题,有很多代码。相反,使用多态性将过于工程化。 如何改进此代码 require 'ostruct' require 'delegate' module BmrCalculator class Calculator def call(sex = :male, measureme

这是我在RubyonRails应用程序中使用的计算的一个伪实现

由于公式仅使用公制单位,如果用户将英制单位设置为默认单位,我必须以某种方式将英制单位转换为公制单位

我已经想出了这个密码

我个人认为,对于这种小问题,有很多代码。相反,使用多态性将过于工程化。 如何改进此代码

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
需要“ostruct”
需要“委托人”
模块BMR计算器
类计算器
def呼叫(性别=:男性,测量单位=:公制)
user=OpenStruct.new(性别:性别,体重:2,身高:2,测量单位:测量单位)
如果度量单位==:英制#不喜欢它
用户=ImperialToMetricDecorator.new(用户)
结束
BmrCalculator.new.bmr(用户)
结束
类BMR计算器
def bmr(用户)
如果user.sex==:男性
将user.inspect放入
将1*user.weight+2*user.height+3设置为#此公式仅适用于公制单位
其他的
将user.inspect放入
将6*user.weight+3*user.height+5计算在内,此公式仅适用于公制单位
结束
结束
结束
结束
类ImperialToMetricDecorator
您可以通过使用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
类长度
这看起来更像是一段代码,但实际上它更易于阅读、测试和维护。

除非您“遭受”if语句的困扰,否则我不会说它们一定很糟糕。多态性好的原因之一是当您需要添加第三个/第四个/第五个案例时。对于男性和女性,几乎可以保证你不会。另一方面,如果您发现由于新的需求,更改if语句开始变得痛苦,那么就进行设计更改,使之更容易。