0

私が欲しいのは、初期化子を介して渡されたパラメーターに基づいて、メソッドを委任するクラスを決定する単一の API です。以下に基本的な例を示します。

module MyApp
  class Uploader
    def initialize(id)
      # stuck here
      # extend, etc. "include Uploader#{id}"
    end
  end
end

# elsewhere
module MyApp
  class UploaderGoogle
    def upload(file)
      # provider-specific uploader
    end
  end
end

私の望む結果:

MyApp::Uploader('Google').upload(file)
# calls MyApp::UploaderGoogle.upload method

上記はデモンストレーションのみを目的としていることに注意してください。アップローダ ID を持つ属性を含むオブジェクトを実際に渡します。これを処理するより良い方法はありますか?

4

2 に答える 2

1

テストしていませんがinclude、モジュールが必要な場合:

module MyApp
  class Uploader
    def initialize(id)
      mod = ("Uploader"+id).constantize
      self.send(:include, mod)
    end
  end
end

モジュールを使用してクラスを拡張する場合:

module MyApp
  class Uploader
    def initialize(id)
      mod = ("Uploader"+id).constantize
      self.class.send(:extend, mod)
    end
  end
end
于 2013-03-27T16:19:48.473 に答える
1

単純なサブクラスが必要なようです。UploaderGoogle < UploaderUploader は基本的なインターフェースを定義し、サブクラスはプロバイダー固有のメソッドを定義し、必要に応じて super を呼び出してアップロードを実行します。以下のテストされていないコード OTTOMH…</p>

module MyApp
    class Uploader
        def initialize(id)
            @id = id
        end

        def upload
            #perform upload operation based on configuration of self. Destination, filename, whatever
        end
    end

    class GoogleUploader < Uploader
        def initialize(id)
            super
            #google-specific stuff
        end

        def upload
            #final configuration/preparation
            super
        end
    end
end

それらの線に沿った何か。渡されたパラメーターに基づいてこれを行うには、caseステートメントを使用します。

klass = case paramObject.identifierString
    when 'Google'
        MyApp::GoogleUploader
    else
        MyApp::Uploader
    end

2 つのこと: 複数の場所でこれを行う場合は、おそらくメソッドに抽出します。第 2 に、ユーザーから入力を取得している場合、たとえば提供された文字列から直接クラス名を作成する場合など、多くのアンチ インジェクション作業を行う必要があります。

于 2013-03-27T15:51:05.287 に答える