2

私は 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

???? ハッシュを使用したことは知っていますが、「オプション ハッシュ」を使用しましたか?

Factory Method は設計パターンです... Ruby でこのパターンを実装する 1 つの方法は、クラス メソッドを使用することです

???? これはファクトリーメソッドとして書かれていますか?

参照用の 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

前もって感謝します

4

1 に答える 1

4

???? クラスメソッドとしてやったのですか?

はい

新しいオブジェクトを作成するよりも良い方法はありましたか?

そうではありませんが、これはレッスンの意図した結果のように見えます。

温度オブジェクトのコンストラクタは、:celcius エントリまたは :fahrenheit エントリのいずれかを含むオプション ハッシュを受け入れる必要があります。

???? ハッシュを使用したことは知っていますが、「オプション ハッシュ」を使用しましたか?

はい、ちょっと

構築後にオプションのハッシュを保持し、すべての計算でそれを参照することは、おそらく最も簡単な解決策ではありません。内部的には、温度の単一の数値インスタンス変数を持つことができます/持つべきです。それはケルビンでさえあるかもしれません。

サブクラスの使用は、適切な単位で内部変数を保持することを意味します (これは必須ではありませんが、テストのポイントは、パブリック インターフェイスの動作を駆動することです。大部分は、適切と思われる内部を自由に実装できます)。 )

投稿で行っていることのいくつかを実行する場合 (たとえば、データの適切なラウンドトリップや遅延変換など) があり、テスト シナリオは非常に単純であるため、選択の結果をどちらの方法でも判断するのは困難です。そのため、他の意見を得ることができます。

あなたがしたことの最大の問題はこれです:

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

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

Factory Method は設計パターンです... Ruby でこのパターンを実装する 1 つの方法は、クラス メソッドを使用することです

???? これはファクトリーメソッドとして書かれていますか?

はい

ファクトリ メソッドは、正しく初期化された新しい有効なオブジェクトを返すメソッドです。

于 2013-04-04T22:03:53.237 に答える