2012-08-15 12 views
7

ユーザーアカウントをインスタンス化します。その後、これはクライアントコードであるGoogle Guiceは別の工場ではありませんか?

public class UserModule extends AbstractModule { 

    public voidSetType(UserType type) { 
    this.type = type; 
    } 

    @Override 
    protected void configure() { 
    if (this.type = UserType.FREE) 
     bind(User.class).to(FreeUser.class); 
    else bind ..... 
    } 
} 

Injector injector = Guice.createInjector(new UserModule().setType(UserType.FREE))); 
私はGoogleのGuiceのを使用している場合

public class UserFactory { 
    public User newUser(UserType type) { 
    if (type == UserType.FREE) return new FreeUser(); 
    } 
} 

User user = UserFactory.newUser(UserType.FREE); //UserType.FREE is an enum 

さて、私は "モジュール" を書き込む必要があります:私はこのような工場を使用することができます

私の質問です: 工場クラスを書く代わりに、私はモジュールクラスを書く必要があります。上記の例から、私は何の利点もありません。 Moduleクラスはリフレクションを使用しますが、ファクトリクラスの代入文よりも処理が遅いです。 Moduleクラスは、ファクトリクラスより単純ではありません。工場を維持する代わりに、モジュールを維持する必要があります。

とにかく本当の利点は何ですか? Google Guiceは別のファクトリークラスではありませんか?

答えて

8

Guice(Dependency Injection)はfactoriesを置き換えるように設計されていないため、利点はありません。それは限られた程度(AssistedInjectとProvidersを参照してください)することができますが、あなたの工場にロジックがあるなら、Guiceを直接の代替品として使用することはできません。

このためのGuiceの方法はまだ工場を持ち、Guiceは工場を投入することです。ユーザーはドメインオブジェクトのように聞こえ、Guiceが依存関係ツリーを挿入する必要はほとんどありません。そうであれば、工場はGuiceを意識して、それぞれのユーザタイプに対してProviderを取るか、または異なるKeyを使用してユーザオブジェクトを作成するためにインジェクションに直接アクセスする必要があります。

DIはすべて依存関係ツリーです。ファクトリは、呼び出し元がそのオブジェクトの実装方法を気にすることなくオブジェクトを生成することに関するものです。彼らはクロスオーバーして一緒に使うことができますが、さまざまな問題に取り組んでいます。

0

本当に "UserType"が必要ですか?

はこの考えてみます。

class FreeUser extends User {...} 
class NonFreeUser extends User {...} 

void configure() { 
    // if Type=Free 
    bind(User.class).annotatedWith(Free.class).to(FreeUser.class); 
    // else 
    bind(User.class).to(NonFreeUser.class) 
} 

、その後

class SomeClassThatNeedsAFreeUser { 
    @Inject 
    @Free 
    private User user; 

} 

あなたはinjector.getInstance(SomeClassThatNeedsAFreeUser.class)を使用するときに、あなたは自動的にFreeSUerが注入されたインスタンスを取得します...私は、これが特定の工場を介した緊密な結合よりはるかに良いアプローチだと思う。

+0

手作業による擬似コードは、不足している部分を修正しない限りコンパイルされません。 –

+0

ユーザーには、登録するアカウントの種類を選択させたいからUserTypeが必要です。彼らがFreeを選択すると、ブラウザは "Free"パ​​ラメータを送信します。これは文字列です。タイプセーフではないため、enumに変換します。 –

2

Guiceは単なる工場ではありません。これは、システム内の共同作業者の構成の定型文を削減し、それらの共同作業者の依存関係を作成する責任を分離することを目的としています。その理由は、次のとおりです。

  1. 削減定型的なコードを(あなたが行う場合には、右)
  2. 依存関係が抽象化され、そのためにスワップインすることができます。
    • テスト時間 - フェイク/モック/スタブ実装実行時に機能が変更されたときに別の実装をスワップインできます。
    • こうした「インタフェース棲み分け」と「シングル責任」

別の答えが言ったようによう

  • 設計原理の考慮事項は、依存性注入や工場間のクロスオーバーがある - 彼らは両方のオブジェクトが管理されていると自分を持っ関与します依存関係は外部システムによって満たされますが、動作は異なります。この場合、工場が必要です。しかし、Dependency-Injectionでは、お互いが適切に動作することが必要な多くの工場がある場合、Guiceのような依存性注入フレームワークを手作業の配線コードや他の定型文なしに工場の相互依存性を管理することができます。

    依存関係がいくつかの種類に分類され、いくつかの種類の注入のみを考慮する傾向があります。もちろん

     
    +======================+=============================+====================+ 
    | Type     | Note      | Inject?   | 
    +======================+=============================+====================+ 
    | Static Dependencies | Inherited types    | N/A    | 
    +----------------------+-----------------------------+--------------------+ 
    | Collaborators  | Services, Factories, etc. | Definitely   | 
    +----------------------+-----------------------------+--------------------+ 
    | Configuration  | Context      | Maybe - be careful | 
    +----------------------+-----------------------------+--------------------+ 
    | Consumables/Data  | Value types     | No - use factories | 
    +======================+=============================+====================+ 
    

    、何のルールは、ハードと高速ではないが、一般的に言って、私は彼らが依存オブジェクトの範囲全体のためのコンテキストとしてimmutably使用されている場合を除き、値の種類を注入しないようにしてみてください。

    ユーザータイプをコンテキストとして使用すると、要求はうまくいきますが、その要求がスコープのオブジェクトすべてに対して「グローバルコンテキスト」として提供され、不変である場合に限ります。しかし、私がそのユーザーを操作しようとしているなら、私はおそらく別のワークフロー/リクエストで工場で管理します。

    自動依存性注入は、アプリケーションの大きな部分である共同編集者、サービス、ユーティリティクラスを管理するのに最適です。もちろん、それをマイクロレベルにまで下げることはできますが、あまりにも夢中にならないように、または複雑さのトレードオフを認識するためには十分に注意する必要があります。はい、あなたのコードは一般的で再利用可能で抽象度が高くなりますが、エフェクトの原因はあまり明確ではありません(実行システムの初期段階でエラーが発生する可能性があります)、フローの線形性が低下し、コードより魔法的に見えるかもしれません。

    手動配線から保存するよりも多くのモジュールコードを記述している場合は、デザインを再検討してください。

    サイドノート: 1.あなたが極端に工場や配線コードをリファクタリングによってGuiceのと依存関係インジェクションフレームワークを導き出すことができますが、工場が具体的に特定のクラスを管理することを目的している - Guiceのはそれほど適していない、定義により、汎用的ですいくつかの種類の工場を置き換える。おそらく、純粋なボイラープレート工場。 2.値の型はインジェクションを使用して注入できますが、値の型(ドメインオブジェクト)は依存関係のサイクルを合法的に必要とする可能性があります。あなたは火を使って遊んでいますが、誰もがスタイルとアプローチを理解できるシステムでは、それは強力です。極端な注意を払って使用してください。

  • 関連する問題