順次、選択、そして繰り返し

プログラミングのことやITのこと、たまに演劇のことも書きます。

手動DIを試してみた

DI(DependencyInjection)とは依存性の注入のこと。

Dependencyは依存という意味らしいがDIについて調べてみると
依存というのは使われる側のオブジェクト(依存オブジェクト)のことを
指してるみたい。

やはりあなた方のDependency Injectionはまちがっている。 — A Day in Serenity (Reloaded) — PHP, FuelPHP, Linux or something

SpringMVCのDIコンテナを使用してソースを書いている時、
DIコンテナインスタンスが生成されているから
newしてインスタンス生成する必要がない。
これは自動的なDIらしい。

なので、今回は手動でDIをやってみる。

DIの種類には3つあるみたい。

  1. インターフェース注入
  2. setter注入
  3. コンストラクタ注入

依存性の注入 - Wikipedia

今回はコンストラクタでの注入でやってみる。

まずはメイン(実行)のクラス(DITest.java)

package di;

/**
 *
 *	手動DIのテスト
 *
 */
public class DITest {
	public static void main(String[] args) {

		//ここで生成するインスタンスを変えると処理結果が変わる
		OutputService outputServiceImpl = new FooOutputServiceImpl();

		//依存性の注入を行っている
		Client client = new Client(outputServiceImpl);

		client.execute();

	}

}

依存性を注入するクラス(Client.java)

package di;

/**
 *
 * クライアントクラス
 * このクラスではnewでインスタンスを生成していないため
 * 依存性は無い
 *
 */
public class Client {

	private OutputService outputServiceImpl;

	/**
	 * コンストラクタ
	 */
	public Client(OutputService outputService) {

		/* コンストラクタ・インジェクション */
		this.outputServiceImpl = outputService;

	}

	/**
	 * 実行メソッド
	 */
	public void execute() {

		outputServiceImpl.execute();

	}

}

インターフェース(OutputService.java)

package di;

public interface OutputService {

	void execute();
}

実装クラス1(HogeOutputServiceImpl.java)

package di;

public class HogeOutputServiceImpl implements OutputService {

	@Override
	public void execute() {
		System.out.println("Hoge");

	}

}

実装クラス2(FooOutputServiceImpl.java)

package di;

public class FooOutputServiceImpl implements OutputService {

	@Override
	public void execute() {
		System.out.println("Foo");
	}

}

DITestクラスでClientクラスのインスタンスを生成しているが、
生成時にFooOutputServiceImplクラスのインスタンスを引数で渡している。
その部分で依存性の注入が行われている。
この場合、Clientクラスのコンストラクタで依存性の注入を行っているため
コンストラクタインジェクション」という。

実際に手動でDIをしてみると、ただnewしていないからDIしているという
訳ではなくそのクラス内でnewが行われず、外部からインスタンスが渡されている
からDIなんだということが理解できてよかった。