8

ユーザーアカウントをインスタンス化したい。私はこのような工場を使うことができます:

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

ここで、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)));

私の質問は、ファクトリクラスを作成する代わりに、モジュールクラスを作成する必要があるということです。そして、上記の例から、私は何の利点も見ていません。Moduleクラスはリフレクションを使用します。これは、ファクトリクラスの代入ステートメントよりも低速です。Moduleクラスは、ファクトリクラスよりも単純ではありません。工場を維持する代わりに、私はモジュールを維持しなければなりません。

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

4

3 に答える 3

8

Guice (依存性注入) はファクトリを置き換えるように設計されていないため、利点は見られません。ある程度は可能ですが (AssistedInject と Providers を参照)、ファクトリにロジックがある場合、Guice を直接の代替として使用できる可能性は低いでしょう。

これに対する Guice の方法は、まだファクトリを持ち、Guice がファクトリを注入することです。User はドメイン オブジェクトのように聞こえ、Guice によって注入された依存関係ツリーを必要としない可能性が高くなります。その場合、ファクトリは Guice を認識し、Provider各 User タイプの を取得するか、Inject に直接アクセスして、異なる を使用して User オブジェクトを作成する必要がありますKey

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

于 2012-08-15T10:07:23.483 に答える
2

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

  1. 定型コードの削減 (適切に行う場合)
  2. 依存関係は抽象化されているため、次の場所で交換できます。
    • テスト時間 - フェイク/モック/スタブの実装を入れ替えることができます
    • 実行時 - 機能が変更されたときに代替実装を交換できます。
  3. 「インターフェースの分離」や「単一の責任」などの設計原則の考慮事項

別の答えが言ったように、依存性注入とファクトリの間にはクロスオーバーがあります。どちらもオブジェクトが管理され、外部システムによって依存関係が満たされていることを伴いますが、動作は異なります。この場合、ファクトリが必要になります。しかし、Dependency-Injection を使用すると、互いに適切に動作することを必要とする多数のファクトリがある場合、Guice のような依存性注入フレームワークを使用して、多くの手動配線コードやその他のボイラープレートなしでファクトリの相互依存性を管理できます。

私は、存在する依存関係をいくつかの異なるタイプに分類し、いくつかのタイプについてのみ注入を検討する傾向があります。

+=====================+========================= ===+====================+
| | タイプ | 注意 | 注射?| |
+=====================+========================= ===+====================+
| | 静的依存関係 | 継承された型 | 該当なし |
+------------------------------------+-------------------------- ---+--------------------+
| | 協力者 | サービス、工場など | 間違いなく |
+------------------------------------+-------------------------- ---+--------------------+
| | 構成 | コンテキスト | たぶん - 注意してください |
+------------------------------------+-------------------------- ---+--------------------+
| | 消耗品/データ | 値の型 | 使用しない工場 |
+=====================+========================= ===+====================+

もちろん、厳格で迅速なルールはありませんが、一般的に言えば、依存オブジェクトのスコープ全体のコンテキストとして不変に使用されている場合を除き、値の型を注入しないようにしています。

したがって、ユーザー型をリクエストのコンテキストとして使用することは問題ありませんが、それが不変であり、スコープがそのリクエストであるすべてのオブジェクトの「グローバル コンテキスト」として提供される場合に限られます。しかし、そのユーザーを操作するつもりなら、おそらく別の別のワークフロー/リクエストで、ファクトリで管理します。

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

手動配線で節約できるよりも多くのモジュール コードを記述していることに気付いた場合は、設計を再検討してください。

補足: 1. ファクトリをリファクタリングし、コードを極限まで配線することで、Guice および Dependency-Injection フレームワークを派生させることができますが、ファクトリは特定のクラスを管理することを特に目的としています。工場。おそらく、定型的な工場です。2. インジェクションを使用して値の型を注入することはできますが、問題が発生します。値の型 (ドメイン オブジェクト) は依存関係のサイクルを正当に要求することができます。Guice などは、サポートしているものの、実際には意図していません。あなたは火遊びをしていますが、誰もがスタイルとアプローチを理解しているシステムでは、それは強力になる可能性があります. 細心の注意を払って使用してください。

于 2012-08-20T14:00:01.373 に答える
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 が自動的に注入されたインスタンスが取得されます。これは、特定のファクトリを介した密結合よりもはるかに優れたアプローチだと思います。

于 2012-08-15T20:07:19.220 に答える