2011-02-09 13 views
7

私は、2つの構築メソッドの1つに基づいて新しいインスタンスを吐き出すためのファクトリメソッドを作成したいクラスを持っています。メモリ内のデータから構築でき、またはファイルに格納されたデータ。私がやりたい何Rubyの静的インスタンスイニシャライザ(ファクトリメソッド)

は建設がクラス内でどのように行われるかのロジックをカプセル化することですので、私はこのように設定されているクラスの静的メソッドを持ってしたいと思います:

class MyAppModel 
    def initialize 
     #Absolutely nothing here - instances are not constructed externally with MyAppModel.new 
    end 

    def self.construct_from_some_other_object otherObject 
     inst = MyAppModel.new 
     inst.instance_variable_set("@some_non_published_var", otherObject.foo) 
     return inst 
    end 

    def self.construct_from_file file 
     inst = MyAppModel.new 
     inst.instance_variable_set("@some_non_published_var", get_it_from_file(file)) 
     return inst 
    end 
end 

がありますメタプログラミング(instance_variable_set)に頼らずにクラス自体からクラスのインスタンスに@some_private_varを設定する方法はありませんか?このパターンはメタポキシング変数をインスタンスに必要とするほど難解ではないようです。私は実際には、MyAppModel以外のクラスでsome_published_varへのアクセスを許可するつもりはないので、例を使用したくありません。 attr_accessor - それは私が何かが欠けているように感じる...

答えて

9

"外側"からインスタンスを作成したくない場合は、あなたが望むものを達成するためのより良い方法かもしれません。

class MyAppModel 
    class << self 
    # ensure that your constructor can't be called from the outside 
    protected :new 

    def construct_from_some_other_object(other_object) 
     new(other_object.foo) 
    end 

    def construct_from_file(file) 
     new(get_it_from_file(file)) 
    end 
    end 

    def initialize(my_var) 
    @my_var = my_var 
    end 
end 
+1

これは非常にいいですし、慣用です。 – Chuck

+0

これは私がやっていたことよりもはるかにクリーンだと思います。コンストラクタにはたくさんのものを渡しますが、とにかく保護されているので、これは大したことではなく、instance_variable_setよりはるかに優れています。 – Matt

関連する問題