2012-01-25 4 views
2

私は多くを楽しんでいるRails AntiPatterns本を読んでいます。ある時点で、作者は構成の良さについて語り、オーダークラスは、OrderConverterと呼ばれる別のクラスへの(他のフォーマットへの)変換の責任を与えている例を示しています。クラスは以下のように定義されていますRails AntiPatterns本 - 構成上の疑問点

class Order < ActiveRecord::Base 
    def converter 
     OrderConverter.new(self) 
    end 
end 

class OrderConverter 
    attr_reader :order 
    def initialize(order) 
     @order = order 
    end 
    def to_xml 
     # ... 
    end 
    def to_json 
     # ... 
    end 
    ... 
end 

そして著者は言う: "このようには、あなたが独立し、簡単にテスト可能なクラス内、変換方法に自分の家を与えるためのPDF版をエクスポートしています。今コール-INGの次のだけの問題:これにについて「

@order.converter.to_pdf 

、私の質問は以下のとおりです。

  • なぜあなたは何注文オブジェクトの前に@? =

    ため

Order.new

をそして実行して変換します:それは次のように作成すべきではない

order.converter.to_pdf 
  • なぜattr_reader :orderラインがOrderConverterに必要とされていますか?それで、OrderConverterオブジェクトからオーダーにアクセスできるようになりましたか?できるようにする必要があります order.converter.to_pdf?それをせずにできるのですがattr_reader

答えて

2

Orderのインスタンスはinitializeメソッドに渡され、(@構文:@orderを使用して)インスタンス変数として格納されます。このように、この変数(変数はインスタンスのスコープを有する)コンバータに他の方法からアクセスすることができる。

class OrderConverter 
    def to_pdf 
    @order.items.each do |item| 
     # Write the order items to the PDF 
    end 
    end 
end 

attr_readerは厳密には必要ではないが、他の方法からOrderオブジェクトにアクセスするための便利な方法であります:

class OrderConverter 
    def to_pdf 
    order.items.each do |item| 
     # Write the order items to the PDF 
    end 
    end 
end 

また、あなたが任意のコンバータインスタンスのうち、オーダーへの参照を取得できるようになります:答えのための

converter.order 
+0

Jeff、私はattr_readerを実行しなくても、他のメソッド(同じクラス内の)からOrderオブジェクトにアクセスできると思いますか?どのコンバーターインスタンスからでも注文を得ることが有用であると私は信じています。 – Nobita

+0

もちろん、コンバーターの内部からそれを追加したのは、 'attr_reader'は単に便利なアクセサだと思います。 'attr_accessor:order'がなければ、' converter.order'を呼び出すと "NoMethodError"が発生します。オーダーへの参照は、この特定のインスタンス外ではアクセスできません。インスタンス変数にはインスタンススコープがあります。 – Jef

+0

申し訳ありませんが、前のコメントに誤って入力/編集しました: 'attr_accessor'(読み書き可能)ではなく' attr_reader'(読み取り専用)を読み込みます。 – Jef

2

変数の先頭にある@は、それをインスタンス変数にします。それがなければ、変数は単にローカル変数になります。私はこれがRailsに関する本だから、このコードがコントローラにあると仮定していると思います。コントローラがメソッド間で共有したい、あるいはビュー内で公開したい変数は、インスタンス変数である必要があります。この場合、@orderはおそらく、要求のパラメータまたはデータベースから取得した値を使用して作成されました。

彼の例とあなたの例の両方がうまくいっていますが、著者はOrderConverterへの呼び出しがどのように見えるかを示していただけで、Orderオブジェクトがどのように作成されたかを無視していたと思います。

attr_reader :orderOrderConverter@orderインスタンス変数のための「ゲッター」メソッドを作成します - それはto_pdfのために必要ではない - converter.orderを経由して戻ってOrderConverterのうちOrderを取得するために使用されるだろう。あなたがこれまでに与えたコードでこれを持つ必要はありませんが、後でそれを必要とするかもしれません。

+0

感謝を。私は2つの答えを受け入れることができればと思っています。私はこのコンセプトを明確にするために両方とも助けてくれました。 – Nobita