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

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

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

Guice User's Guide ■3. Dependency Injection By Hand

手作業でのDependency Injection

The dependency injection pattern aims in part to make unit testing easier. We don't necessarily need a specialized framework to practice dependency injection. You can get roughly 80% of the benefit writing code by hand.

Dependency Injection(依存性の注入)パターンは、 ユニットテストを簡単にすることを目標の一部としています。Dependency Injectionの実践には必ずしも特別なフレームワークは必要ではありませんが、フレームワークを使えば手作業でコードを書く場合に比べておよそ80%の利益があります。

While the client asked the factory for a service in our previous example, with dependency injection, the client expects to have its dependency passed in. Don't call me, I'll call you, so to speak.

先ほどのサンプルで、クライアントがDependency Injectionを使ってファクトリーにサービスの問い合わせをしている間、クライアントはその依存性が渡されることを待機します。いわば、「Don't call me, I'll call you(私を呼ばないで、私があなたを呼び出します ※注:ハリウッドの原則)」といえます。

public class Client {
   
  private final Service service;

  public Client(Service service) {
    this.service = service;
  }

  public void go() {
    service.go();
  }
}

This simplifies our unit test considerably. We can just pass in a mock service and throw everything away when we're done.

これはユニットテストをかなり簡素化します。完了したならモックサービスにただ渡して、すべてを捨てることができます。

public void testClient() {
  MockService mock = new MockService();
  Client client = new Client(mock);
  client.go();
  assertTrue(mock.isGone());
}

We can also tell from the API exactly what the client depends on.

クライアントが何に依存しているかを、APIから正確に読み取ることも出来ます。

Now, how do we connect the client with a service? When implementing dependency injection by hand, we can move all dependency logic into factory classes. This means we need a factory for our client, too.

では、どのようにクライアントとサービスをつなげるのでしょうか?手作業でDependency Injectionを実装したときならば、すべてのファクトリークラスのなかの依存性のロジックを移動することができます。これはクライアントのためのファクトリーが必要なことを意味しているとも言えます。

public static class ClientFactory {

  private ClientFactory() {}

  public static Client getInstance() {
    Service service = ServiceFactory.getInstance();
    return new Client(service);
  }
}

Implementing dependency injection by hand requires roughly the same number of lines of code as plain old factories.

手作業でDependency Injectionを実装すると、Plain Old Factoryと、おおよそ同じ行数のコードが必要になります。