Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
DI(依存性注入)について
伊藤 結
ところで、DIと聞いて
  ピンとくる方はいますか?
DI(依存性注入)とは
なるほど。わからん。
依存性の注入(英: Dependency injection)とは、コンポーネント間の依存関係をプロ
グラムのソースコードから 排除し、外部の設定ファイルなどで注入できるようにするソ
フトウェアパタ...
DI(依存性注入)とは
依存性の注入(英: Dependency injection)とは、コンポーネント間の依存関係をプロ
グラムのソースコードから 排除し、外部の設定ファイルなどで注入できるようにするソ
フトウェアパターンである。英語の頭文...
依存性ってなに?
public class Siphon implements BrewingMethod {
@Override
public String brew() {
return "サイフォンでいれたコーヒー ";
}
}
public class ...
public class Siphon implements BrewingMethod {
@Override
public String brew() {
return "サイフォンでいれたコーヒー ";
}
}
public class ...
クラスAからクラスBを直接インスタンス化している時、
クラスAはクラスBがないと動きません。
このような状態は
クラスAとクラスBが依存関係にある、
クラスAはクラスBに依存しているといえます。
今回の例でいうと、
 CfeeShopAppとC...
注入ってなに?
実際のコードで説明します
DIコンテナを使って、
  実際にDIをやってみよう!
DIコンテナとは
● すごく簡単に言うと、「XXにこのクラスのオブジェクトを注入してね」
という設定を書いておくとDI(依存性の注入)を実行するよくんのこと。
今回はJava向けのDaggerというDIコンテナを使います。
@Module(injects = CoffeeShopApp.class)
public class BrewingMethodModule {
@Provides
public BrewingMethod provideBrewingMet...
@Module(injects = CoffeeShopApp.class)
public class BrewingMethodModule {
@Provides
public BrewingMethod provideBrewingMet...
Daggerが依存性が注入されたオブジェクトを生成することで、
CofeeShopAppから直接インスタンス化する記述をなくすことができ、
以下のモジュール間の依存関係を外部に逃がすことができました。
 CofeeShop ー Siphon
 ...
で、DI使うと
   なにがよくなるの?
DIを使う場合の利点
● モジュール間の依存関係を弱めることができる(保守性が高まる)
● 単体テストが楽になる
(Aモジュールが完成する前にBモジュールをテストできる、外から特定のモジュールをモック
に差し替えることができる)
実際やってみて...
public class CoffeeShopTest {
@Inject CoffeeShop coffeeShop;
@Inject BrewingMethod brewingMethod;
@Before
public void setU...
public class CoffeeShopTest {
@Inject CoffeeShop coffeeShop;
@Inject BrewingMethod brewingMethod;
@Before
public void setU...
public class CoffeeShopTest {
@Inject CoffeeShop coffeeShop;
@Inject BrewingMethod brewingMethod;
@Before
public void setU...
DIコンテナって
他にはどんなのがあるの?
代表的なDIコンテナ
● Spring Framework
● JavaEE (CDI)
● Seasar2
● Zend Framework 2
● Dagger
● Dagger2
● Proton
● RoboGuice
なんかJavaばっかりじゃね?
言語とDIコンテナ
● Javaなどの静的言語では色々と種類があるが、
RubyやPythonなどの動的言語ではあまり使われていない(と思う)。
私は一時DIについて関心を持って、いろいろ調べてみたし、 自分でDIコンテナ
を実装してみたりもし...
どんな所でDIを使うべき?
DIの使いどころ
● (当たり前ですが) DIを前提にしたフレームワークを使用するとき。
● Javaを使用しており、テスト駆動開発(TDD)とかテストコードを書くことが前提のプロジェクト。
● 実装があるモジュールに依存してるが、そのモジュー...
ご清聴ありがとうございました
Nächste SlideShare
Wird geladen in …5
×

DI(依存性注入)について

14.220 Aufrufe

Veröffentlicht am

DI(依存性注入)について

Veröffentlicht in: Technologie
  • Thanks to all your information and revision techniques, I got an A* in my Maths GCSE exam... I was predicted a C but I wanted to go that extra mile and make my parents proud. I struggled with Algebra but using your resources, I found it easy and conquered the challenge. Thank you so much! ■■■ http://t.cn/AirraVnG
       Antworten 
    Sind Sie sicher, dass Sie …  Ja  Nein
    Ihre Nachricht erscheint hier

DI(依存性注入)について

  1. 1. DI(依存性注入)について 伊藤 結
  2. 2. ところで、DIと聞いて   ピンとくる方はいますか?
  3. 3. DI(依存性注入)とは なるほど。わからん。 依存性の注入(英: Dependency injection)とは、コンポーネント間の依存関係をプロ グラムのソースコードから 排除し、外部の設定ファイルなどで注入できるようにするソ フトウェアパターンである。英語の頭文字からDIと略される。 wikipediaより https://ja.wikipedia.org/wiki/依存性の注入
  4. 4. DI(依存性注入)とは 依存性の注入(英: Dependency injection)とは、コンポーネント間の依存関係をプロ グラムのソースコードから 排除し、外部の設定ファイルなどで注入できるようにするソ フトウェアパターンである。英語の頭文字からDIと略される。 wikipediaより https://ja.wikipedia.org/wiki/依存性の注入 言葉の意味から考えてみよう!
  5. 5. 依存性ってなに?
  6. 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. 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(抽出方法) の実装クラス
  8. 8. クラスAからクラスBを直接インスタンス化している時、 クラスAはクラスBがないと動きません。 このような状態は クラスAとクラスBが依存関係にある、 クラスAはクラスBに依存しているといえます。 今回の例でいうと、  CfeeShopAppとCoffeeShop  CoffeeShopとSiphone の間で依存関係があるということになります
  9. 9. 注入ってなに?
  10. 10. 実際のコードで説明します
  11. 11. DIコンテナを使って、   実際にDIをやってみよう!
  12. 12. DIコンテナとは ● すごく簡単に言うと、「XXにこのクラスのオブジェクトを注入してね」 という設定を書いておくとDI(依存性の注入)を実行するよくんのこと。 今回はJava向けのDaggerというDIコンテナを使います。
  13. 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. 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オブジェクトが生成されま す。
  15. 15. Daggerが依存性が注入されたオブジェクトを生成することで、 CofeeShopAppから直接インスタンス化する記述をなくすことができ、 以下のモジュール間の依存関係を外部に逃がすことができました。  CofeeShop ー Siphon  CoffeeShopApp ー CofeeShop
  16. 16. で、DI使うと    なにがよくなるの?
  17. 17. DIを使う場合の利点 ● モジュール間の依存関係を弱めることができる(保守性が高まる) ● 単体テストが楽になる (Aモジュールが完成する前にBモジュールをテストできる、外から特定のモジュールをモック に差し替えることができる) 実際やってみて、特にテストコードを書くとき、Mockオブ ジェクトに差し替えてテストながせるのが心地よかったで す。
  18. 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. 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. 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()が呼ばれ た際に”テストコーヒー”が返却されるよ う設定。
  21. 21. DIコンテナって 他にはどんなのがあるの?
  22. 22. 代表的なDIコンテナ ● Spring Framework ● JavaEE (CDI) ● Seasar2 ● Zend Framework 2 ● Dagger ● Dagger2 ● Proton ● RoboGuice
  23. 23. なんかJavaばっかりじゃね?
  24. 24. 言語とDIコンテナ ● Javaなどの静的言語では色々と種類があるが、 RubyやPythonなどの動的言語ではあまり使われていない(と思う)。 私は一時DIについて関心を持って、いろいろ調べてみたし、 自分でDIコンテナ を実装してみたりもした。 でも、RubyでならDIコンテナがわずか20行で記述で きる上、 よく考えてみたら、その20行も、なくてもほぼ同じことが簡単に実現で きることに気がついた時、 DIってのは硬直した言語のための技術なんだと気 がついた。 Matzにっき より http://www.rubyist.net/~matz/20091003.html
  25. 25. どんな所でDIを使うべき?
  26. 26. DIの使いどころ ● (当たり前ですが) DIを前提にしたフレームワークを使用するとき。 ● Javaを使用しており、テスト駆動開発(TDD)とかテストコードを書くことが前提のプロジェクト。 ● 実装があるモジュールに依存してるが、そのモジュールは未完成、でも単体テストを始めない といけないんだよ〜みたいなことになりそうなとき。 採用したときのコスト(学習コストなど)に比べて、モ ジュール間の依存関係を弱めることが重要な時に使用 するべき。 何でもかんでもDIすればいいってもんでもない。
  27. 27. ご清聴ありがとうございました

×