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


Dependency injection with Guice

Testable code with less boilerplate


Level: 中級 Nicholas Lesiecki (ndlesiecki@apache.org), Software engineer, Google

Guice is Google's open source dependency injection framework for Java〓 development. It enables better testing and modularity by taking away the pain of writing your own factories. Nicholas Lesiecki offers a tour of the most important Guice concepts that will leave you ready to Guice up your applications.


Guice is a dependency injection (DI) framework. I've suggested for years that developers use DI, because it improves maintainability, testability, and flexibility. By watching engineers react to Guice, I've learned that the best way to convince a programmer to adopt a new technology is to make it really easy. Guice makes DI really easy, and as a result, the practice has taken off at Google. I hope to continue in the same vein in this article by making it really easy for you to learn Guice.

Guicedependency injection (DI)フレームワークです。私はここ数年、開発者にDIを使うことを推奨してきました。なぜなら、DIを使うことでメンテナンス性、テスト容易性、柔軟性が好転するからです。新しい技術を採用するために、プログラマを説得する一番良い方法は、それを実際に簡単に使ってもらうことです。Guiceに対するエンジニアの反応を見ていると、GuiceはDIを本当に簡単なものにしてくれます。そして、結果としてその運営はGoogoleを離れました。私は、流れのまま続くことを希望しています。この記事でGuiceを学ぶこととても簡単にすることで、それを実現したいと思います。

Guice 2.0 beta

As I write this, the Guice team is working hard on Guice 2.0 and expects to release before the end of 2008. An early beta is posted on the Google Code download site (see Resources). This is good news, because the Guice team has added features that will make your Guice code easier to use and understand. The beta lacks some features that will make it into the final version, but it's stable and high quality. In fact, Google uses the beta version in production software. I advise you to do the same. I've written this article specifically for Guice 2.0, covering some new Guice features and glossing over features from 1.0 that have been deprecated. The Guice team has assured me that the features I cover won't change between the current beta and final release.

早期Bata版が、Google Code ダウンロードサイト上にアップされました。(参照)

If you already understand DI and know why you'd want a framework to help you with it, you can skip to the Basic injection with Guice section. Otherwise, read on to learn about DI's benefits.


The case for DI

I'll start with an example. Let's say I'm writing a superhero application, and I'm implementing a hero named Frog Man. Listing 1 contains the code, as well as my first test. (I hope I don't need to convince you of the value of writing unit tests.)

Frog Manという名前のヒーローを実装していきます。"リスト1"にコードと最初のテストコードも一緒に記述します。

リスト1. ヒーロー と 彼に関するテスト

public class FrogMan {
  private FrogMobile vehicle = new FrogMobile();
  public FrogMan() {}
  // crime fighting logic goes here...

public class FrogManTest extends TestCase {
 public void testFrogManFightsCrime() {
    FrogMan hero = new FrogMan();
    //make some assertions...

All seems well until I try running the test, whereupon I get the exception in Listing 2:

リスト2. 面倒な依存性

java.lang.RuntimeException: Refinery startup failure.
  at HeavyWaterRefinery.<init>(HeavyWaterRefinery.java:6)
  at FrogMobile.<init>(FrogMobile.java:5)
  at FrogMan.<init>(FrogMan.java:8)
  at FrogManTest.testFrogManFightsCrime(FrogManTest.java:10)

It seems that the FrogMobile constructs a HeavyWaterRefinery and, well, let's just say there's no way I can construct one of those in my test. I can do so in production, sure, but no one will grant me a second refinery permit just for testing. In real life, you're not likely to refine deuterium oxide, but you are likely to depend on remote servers and beefy databases. The principle is the same: These dependencies are hard to start and slow to interact with, and they cause your tests to fail more often than they should.


Enter DI

To avoid this problem, you can create an interface (for example, Vehicle) and have your FrogMan class accept the Vehicle as a constructor argument, as in Listing 3:


リスト3. インターフェイスへの依存、そしてインジェクト

public class FrogMan {
  private Vehicle vehicle;

  public FrogMan(Vehicle vehicle) {
    this.vehicle = vehicle;
  // crime fighting logic goes here...

This idiom is the essence of DI ― have your classes accept their dependencies through references to interfaces instead of constructing them (or using static references). Listing 4 shows how DI makes your test easier:


Listing 4. テストで面倒な依存性の代わりにモックを使う方法

static class MockVehicle implements Vehicle {
  boolean didZoom;

  public String zoom() {
    this.didZoom = true;
    return "Mock Vehicle Zoomed.";

public void testFrogManFightsCrime() {
  MockVehicle mockVehicle = new MockVehicle();

  FrogMan hero = new FrogMan(mockVehicle);

  // other assertions

This test uses a hand-written mock object to replace the FrogMobile. Not only does DI free the test from the painful refinery startup cost, but it also keeps the test from knowing about FrogMobile. All it needs is the Vehicle interface. In addition to making tests easier, DI also helps your code's overall modularity and maintainability. Now, if you want to switch the FrogMobile for the FrogBarge, you can do so without modifying FrogMan. All FrogMan depends on is the interface.


There's a catch, however. If you're like me the first time I read about DI, you're thinking: "Great, now all FrogMan's callers have to know about the FrogMobile (and the refinery, and the refinery's dependencies, and so on...)." But if that were true, DI would never have caught on. Instead of forcing callers to assume the burden, you can write factories to manage the creation of an object and its dependencies.


Factories are where frameworks come in. Factories require a lot of tedious, repetitive code. In the best case, they annoy the program author (and readers), and in the worst, they never get written because of the inconvenience. Guice and other DI frameworks serve as flexible "super factories" that you configure to build your objects. Configuring the framework is a lot easier than writing your own factories. As a result, programmers write more code in a DI style. More tests, better code, and happy programmers follow.