More Related Content Similar to DI(依存性注入)について (20) DI(依存性注入)について6. public class Siphon implements BrewingMethod {
@Override
public String brew() {
return "サイフォンでいれたコーヒー ";
}
}
public class CoffeeShop {
public String brewCoffee() {
BrewingMethod siphone = new Siphone();
return siphone.brew() + "が出来上がりました [_]P";
}
}
public class CoffeeShopApp {
public static void main(String... args) {
CoffeeShop coffeeShop = new CoffeeShopApp();
System.out.println(coffeeShop.brewCoffee());
}
}
7. public class Siphon implements BrewingMethod {
@Override
public String brew() {
return "サイフォンでいれたコーヒー ";
}
}
public class CoffeeShop {
public String brewCoffee() {
BrewingMethod siphone = new Siphone();
return siphone.brew() + "が出来上がりました [_]P";
}
}
public class CoffeeShopApp {
public static void main(String... args) {
CoffeeShop coffeeShop = new CoffeeShopApp();
System.out.println(coffeeShop.brewCoffee());
}
}
プログラムの実行クラス
BrewingMethod(抽出方法)
の実装クラス
13. @Module(injects = CoffeeShopApp.class)
public class BrewingMethodModule {
@Provides
public BrewingMethod provideBrewingMethod() {
return new Siphon();
}
}
public class CoffeeShop {
// Siphonオブジェクトが注入される
@Inject BrewingMethod brewingMethod;
....
}
public class CoffeeShopApp {
//兄弟クラスがないので設定なしでCoffeeShopオブジェクトが注入される
@Inject CoffeeShop coffeeShop;
public void run() {
System.out.println(coffeeShop.brewCoffee());
}
public static void main(String... args) {
// Daggerのオブジェクト生成(設定を読み込んで、各オブジェクトが注入されたCoffeeShopAppオブジェクトを生成)
ObjectGraph objectGraph = ObjectGraph.create(new BrewingMethodModule());
CoffeeShopApp coffeeShopApp = objectGraph.get(CoffeeShopApp.class);
coffeeShopApp.run();
}
14. @Module(injects = CoffeeShopApp.class)
public class BrewingMethodModule {
@Provides
public BrewingMethod provideBrewingMethod() {
return new Siphon();
}
}
public class CoffeeShop {
// Siphonオブジェクトが注入される
@Inject BrewingMethod brewingMethod;
....
}
public class CoffeeShopApp {
//兄弟クラスがないので設定なしでCoffeeShopオブジェクトが注入される
@Inject CoffeeShop coffeeShop;
public void run() {
System.out.println(coffeeShop.brewCoffee());
}
public static void main(String... args) {
// Daggerのオブジェクト生成(設定を読み込んで、各オブジェクトが注入されたCoffeeShopAppオブジェクトを生成)
ObjectGraph objectGraph = ObjectGraph.create(new BrewingMethodModule());
CoffeeShopApp coffeeShopApp = objectGraph.get(CoffeeShopApp.class);
coffeeShopApp.run();
}
@Moduleで注入先クラスを指定
@Providesを付与したメソッドで、注入するオ
ブジェクトを生成する処理を記述。
Daggerライブラリのオブジェクト生成処理
(BrewingMethodModuleの設定を読み込
んで、CoffeeShopAppオブジェクトを生
成)。
@Injectが付与されている
CofeeShopApp#cofeeShop,
CofeeShop#resingMethod
にオブジェクトが注入された状態の
CoffeeShopAppオブジェクトが生成されま
す。
18. public class CoffeeShopTest {
@Inject CoffeeShop coffeeShop;
@Inject BrewingMethod brewingMethod;
@Before
public void setUp() {
ObjectGraph.create(new TestModule()).inject(this);
}
@Module(includes = BrewingMethodModule.class,
injects = CoffeeShopTest.class,
overrides = true)
static class TestModule {
@Provides
@Singleton
public BrewingMethod provideBrewingMethod() {
return Mockito.mock(BrewingMethod.class);
}
}
@Test
public void testBrewCoffee() {
Mockito.when(brewingMethod.brew()).thenReturn("テストコーヒー");
String result = coffeeShop.brewCoffee();
Mockito.verify(brewingMethod, Mockito.times(1)).brew();
assertThat(result, is("テストコーヒーが出来上がりました [_]P"));
}
DIを利用したテストコードの一例
CoffeShopのテストコードです。
BrewingMethodクラスのオブジェクトは
モックに置き換えてテストを実行してい
ます。
CoffeeShopから
BrewingMethod#brewメソッドが1回呼
ばれていること、
CoffeeShop#brewCoffeeメソッドの結
果が正しいこと
を確認するテストコードです。
19. public class CoffeeShopTest {
@Inject CoffeeShop coffeeShop;
@Inject BrewingMethod brewingMethod;
@Before
public void setUp() {
ObjectGraph.create(new TestModule()).inject(this);
}
@Module(includes = BrewingMethodModule.class,
injects = CoffeeShopTest.class,
overrides = true)
static class TestModule {
@Provides
@Singleton
public BrewingMethod provideBrewingMethod() {
return Mockito.mock(BrewingMethod.class);
}
}
@Test
public void testBrewCoffee() {
Mockito.when(brewingMethod.brew()).thenReturn("テストコーヒー");
String result = coffeeShop.brewCoffee();
Mockito.verify(brewingMethod, Mockito.times(1)).brew();
assertThat(result, is("テストコーヒーが出来上がりました [_]P"));
}
BrewingMethodModuleを、BrewingMethod
のモックを返却するように上書きしている。
20. public class CoffeeShopTest {
@Inject CoffeeShop coffeeShop;
@Inject BrewingMethod brewingMethod;
@Before
public void setUp() {
ObjectGraph.create(new TestModule()).inject(this);
}
@Module(includes = BrewingMethodModule.class,
injects = CoffeeShopTest.class,
overrides = true)
static class TestModule {
@Provides
@Singleton
public BrewingMethod provideBrewingMethod() {
return Mockito.mock(BrewingMethod.class);
}
}
@Test
public void testBrewCoffee() {
Mockito.when(brewingMethod.brew()).thenReturn("テストコーヒー");
String result = coffeeShop.brewCoffee();
Mockito.verify(brewingMethod, Mockito.times(1)).brew();
assertThat(result, is("テストコーヒーが出来上がりました [_]P"));
}
本クラスへの依存性注入の実行
CoffeeShop#brewingMethod、
brewingMethodへ
BrewingMethodのMockを注入する。
(TestModule#provideBrewingMethodに
Singletonアノテーションを付与しているので
すべて同じオブジェクトが注入される)。
注入した、モックオブジェクトの振る舞
いを設定して、テストを実行。
※BrewingMethod#brew()が呼ばれ
た際に”テストコーヒー”が返却されるよ
う設定。
26. DIの使いどころ
● (当たり前ですが) DIを前提にしたフレームワークを使用するとき。
● Javaを使用しており、テスト駆動開発(TDD)とかテストコードを書くことが前提のプロジェクト。
● 実装があるモジュールに依存してるが、そのモジュールは未完成、でも単体テストを始めない
といけないんだよ〜みたいなことになりそうなとき。
採用したときのコスト(学習コストなど)に比べて、モ
ジュール間の依存関係を弱めることが重要な時に使用
するべき。
何でもかんでもDIすればいいってもんでもない。