我正在经历 Test First 的 Ruby 项目,并且我已经完成了其中的大部分项目,但是 08_Temperature_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
提前谢谢
最佳答案
???? Did I do it as a class method?
是
Was there another/ better way than creating a new object?
并非如此,这看起来像是本类(class)的预期结果。
The temperature object's constructor should accept an options hash which contains either a :celcius entry or a :fahrenheit entry.
???? I know I used a hash, but did I use an 'options hash'?
是的,有点
在构造后保留选项哈希,并在所有计算中引用它可能不是最简单的解决方案。在内部,您可以/应该有一个用于温度的数字实例变量。甚至可能是开尔文。
子类的使用意味着它们在适当的单位中保留一个内部变量(尽管这不是必需的,但测试的目的是驱动公共(public)接口(interface)行为,在很大程度上,您可以自由地实现内部结构你认为合适)
在某些情况下,您需要做一些您在帖子中所做的事情(例如,正确地往返数据或惰性转换),并且测试场景非常简单,因此您的选择的后果很难以任何方式判断。所以你可能会得到其他意见。
你所做的最大的问题是:
hash = { :c => 25 }
t = Temperature.new( hash )
# This reaches inside the new object and changes its state, breaking encapsulation:
hash[:c] = 30
Factory Method is a design pattern... One way to implement this pattern in Ruby is via class methods
???? Is this written as a factory method?
是
工厂方法只是返回一个新的、有效的、正确初始化的对象的方法。
关于ruby - Test First 的温度对象项目 - 它通过了所有测试,但这就是我应该学习的内容吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15822025/