Проект 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 - через методы классов.
???? Это написано как фабричный метод?
да
Фабричный метод - это просто метод, который возвращает новый и действительный, правильно инициализированный объект.