Проект Test First для объекта температуры - он проходит все тесты, но это то, что я должен был изучить?

Я прохожу проекты Ruby в Test First, и я выполнил большинство из них, но 08_tempera_object меня сильно смущает, не в последнюю очередь потому, что, несмотря на то, что я заставил его работать, пройдя тесты, я не уверен, что сделал это так, как они хотели,

Вот что я придумал:

class Temperature
    def initialize(options = {})
        @options = options
        #@options = Hash.new { |h, key| h[key] = [] }
    end
    #end

    def in_fahrenheit
        @options.key?(:f) ? @options[:f] : (@options[:c] * 9.0 / 5) + 32
    end

    def in_celsius
        @options.key?(:c) ? @options[:c] : (@options[:f] - 32) * 5.0 / 9
    end

    def self.from_fahrenheit(num)
        self.new(:f => num)
    end

    def self.from_celsius(num)
        self.new(:c => num)
    end
end

class Celsius < Temperature

    def initialize(num, options = {})
        @options = options
        @options[:c] = num
    end

    def in_fahrenheit
        super
    end

    def in_celsius
        super
    end
end

class Fahrenheit < Temperature

    def initialize(num, options = {})
        @options = options
        @options[:f] = num
    end

    def in_fahrenheit
        super
    end

    def in_celsius
        super
    end
end

Из инструкции:

Не забудьте определить from_celsius фабричный метод как метод класса, а не метод экземпляра.

???? Я сделал это как метод класса? Был ли другой / лучший способ, чем создание нового объекта?

Конструктор объекта температуры должен принимать хеш опций, который содержит :celcius запись или :fahrenheit запись.

???? Я знаю, что использовал хеш, но использовал ли я хэш опций?

Фабричный метод - это шаблон проектирования. Один из способов реализовать этот шаблон в Ruby - через методы классов.

???? Это написано как фабричный метод?

Вот несколько примеров тестов Rspec для справки:

describe Temperature do

  describe "can be constructed with an options hash" do
    describe "in degrees fahrenheit" do
      it "at 50 degrees" do
        Temperature.new(:f => 50).in_fahrenheit.should == 50
      end

 describe "can be constructed via factory methods" do

    it "in degrees celsius" do
      Temperature.from_celsius(50).in_celsius.should == 50
      Temperature.from_celsius(50).in_fahrenheit.should == 122
    end

  # test-driving bonus:
  #
  # 1. make two class methods -- ftoc and ctof
  # 2. refactor to call those methods from the rest of the object
  #
  # run *all* the tests during your refactoring, to make sure you did it right
  #
  describe "utility class methods" do

  end

  # Here's another way to solve the problem!
  describe "Temperature subclasses" do
    describe "Celsius subclass" do
      it "is constructed in degrees celsius" do
        Celsius.new(50).in_celsius.should == 50
        Celsius.new(50).in_fahrenheit.should == 122
      end

      it "is a Temperature subclass" do
        Celsius.new(0).should be_a(Temperature)
      end
    end

Заранее спасибо

1 ответ

Решение

???? Я сделал это как метод класса?

да

Был ли другой / лучший способ, чем создание нового объекта?

Не совсем, это похоже на предполагаемый результат урока.

Конструктор объекта температуры должен принимать хэш опций, который содержит либо запись: celcius, либо запись: fahrenheit.

???? Я знаю, что использовал хеш, но использовал ли я хэш опций?

Да вроде

Сохранять хэш параметров после построения и ссылаться на него во всех вычислениях, вероятно, не самое простое решение. Внутри вы можете / должны иметь единственную числовую переменную экземпляра для температуры. Это может быть даже Кельвин.

Использование подклассов подразумевает, что они хранят внутреннюю переменную в соответствующих единицах (хотя это и не требуется, смысл тестов состоит в том, чтобы управлять поведением открытого интерфейса, в значительной степени вы можете свободно внедрять внутренние компоненты по своему усмотрению)

Есть случаи, когда вы делаете что-то из того, что вы делаете в своем посте (например, правильное округление данных или ленивые преобразования), и сценарий тестирования очень прост, поэтому последствия вашего выбора трудно судить в любом случае. Таким образом, вы можете получить другие мнения.

Самая большая проблема с тем, что вы сделали, заключается в следующем:

hash = { :c => 25 }
t = Temperature.new( hash )

# This reaches inside the new object and changes its state, breaking encapsulation:
hash[:c] = 30

Фабричный метод - это шаблон проектирования. Один из способов реализовать этот шаблон в Ruby - через методы классов.

???? Это написано как фабричный метод?

да

Фабричный метод - это просто метод, который возвращает новый и действительный, правильно инициализированный объект.

Другие вопросы по тегам