手作業での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と、おおよそ同じ行数のコードが必要になります。