レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

Guice2.0 beta 紹介記事の翻訳(3)

原文:IBM Developer : Sorry, that page no longer exists
訳1:Guice2.0 beta 紹介記事の翻訳(1) - 山本大の日記
訳2:Guice2.0 beta 紹介記事の翻訳(2) - 山本大の日記

インジェクションの別のやり方(Other forms of injection)

So far, I've shown @Inject applied to constructors. When it finds this annotation, Guice picks through the constructor arguments and tries to find a configured binding for each of them. This is known as constructor injection. According to the Guice best practices guide, constructor injection is the preferred way to ask for your dependencies. But it's not the only way. Listing 9 shows another way to configure the FrogMan class:


ここまでで、私は@Injectをコンストラクタに適用する方法を紹介しました。このアノテーションを見つけたら、
Guiceはコンストラクタ引数のそれぞれに設定されたバインディングを当てはめられないかを調べます。
これはコンストラクタインジェクションとして知られています。
Guiceのベストプラクティスガイドによると、コンストラクタインジェクションは
依存性を問い合わせるのにおすすめな方法です。しかし、その方法だけというわけではありません。
リスト9はFrogManクラスに設定するための別の方法を紹介しています。


リスト 9. メソッドインジェクション (Method injection)

public class FrogMan{
  private Vehicle vehicle;

  @Inject
  public void setVehicle(Vehicle vehicle) {
    this.vehicle = vehicle;
  }
//etc. ...


Notice that I've gotten rid of the injected constructor and instead have a method tagged with @Inject. Guice calls this method immediately after it constructs my hero. Fans of the Spring Framework may see this as "setter injection." However, Guice cares only about @Inject; your method can be named anything you like, and it can take multiple parameters. It can be package-protected or private too.
If you think Guice's decision to access private methods seems intrusive, wait until you see Listing 10, in which FrogMan uses field injection


インジェクトしたコンストラクターを取り除いた代わりに@Injectアノテーションでタグ付けされたメソッドがあることに注意して下さい。Guiceはヒーローを構築した後、即座にこのメソッドを呼び出します。Spring Frameworkの愛好者はこれを"セッターインジェクション"と見るでしょう。しかしながら、Guiceは@Injectについてのみ扱います。つまり、対象とするメソッドでは何でも好きな名前を付けてもよく、さらに複数パラメータをとることもできます。パッケージプロテクテッドやプライベートなメソッドでも同様です。
もし、プライベートメソッドにアクセスするというGuiceの決定を信用できないと思ったとしても、リスト10を見るまでは待ってください。ここではFrogManフィールドインジェクションを使っています。


リスト10. フィールドインジェクション(Field injection)

public class FrogMan {
  @Inject private Vehicle vehicle;
  public FrogMan(){}
//etc. ...

Again, all Guice cares about is the @Inject annotation. It finds any fields you annotate and tries to inject the appropriate dependency.


ここでも結局、Guiceは@Injectアノテーションについてしか扱いません。Guiceはアノテートされたフィールドを見つけ、適切な依存性を注入しようと試みます。

どっちが良いの? (Which one is best?)

All three versions of FrogMan exhibit the same behavior: Guice injects the appropriate Vehicle when they're constructed. However, I prefer constructor injection, as do Guice's authors. Here's a quick analysis of the three styles:


3つのバージョンのFrogManは、同じ振る舞いをしているように見えます。Guiceインスタンス構築時に適切な乗り物(Vehicle)をインジェクトします。しかしながら、私はGuiceの作者と同じく、コンストラクタインジェクションをおすすめします。以下に、3つのスタイル毎の簡単な分析を述べます。

  • Constructor injection is straightforward. Because Java technology guarantees constructor invocation, you don't need to worry about objects arriving in an uninitialized state ― whether or not Guice creates them. You can also mark your fields final.
  • Field injection harms testability, especially if you mark the fields private. That defeats one of the main aims of DI. You should use field injection only in very limited circumstances.
  • Method injection can be useful if you don't control a class's instantiation. You can also use it if you have a superclass that needs some dependencies. (Constructor injection makes this difficult.)

  • コンストラクタインジェクションは、正統なやり方です。なぜなら、Java技術ではコンストラクタによる初期化を推奨しているからです。Guiceで生成していなくても同じことが言えるのですが、コンストラクタによってオブジェクトを生成することでオブジェクトが正しく初期化されていない状態で生存しているかもしれないという心配がなくなります。また、この方法であればフィールドにFilanlの修飾子をつけることが可能です。
  • フィールドインジェクションは、テストしやすさを阻害します。特に、フィールドをプライベートにしたときには顕著です。これはDIの主な目的の一つを駄目にします。そのためフィールドインジェクションはかなり限られた状況でのみ利用すべきです。
  • メソッドインジェクションは、クラスのインスタンス化をコントロールできない場合に便利です。また、いくつかの依存性を必要とするスーパークラスにも使えます。(コンストラクターインジェクションではこれは難しい作業です。)