dependency injectionとは
TRANSCRIPT
![Page 1: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/1.jpg)
Dependency Injectionとはdoi
![Page 2: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/2.jpg)
依存とはDependency
![Page 3: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/3.jpg)
依存とは• 僕はパソコンが無いと生きていけない
• 僕はパソコンに依存
• ネットがないと僕は生きていけない
• 僕はネットとパソコンが無いと成立しない状態
![Page 4: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/4.jpg)
例えば
![Page 5: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/5.jpg)
Codeclass Enemy { int hp; public void damage(int damage) { hp -= damage; } }
class Boss { int hp; public void damage(int damage) { hp -= damage; } }
class Player { public void attackEnemy(Enemy enemy) { enemy.damage( 10 ); } public void attackBoss (Boss boss) { boss.damage( 10 ); } }
![Page 6: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/6.jpg)
Codeclass GameManager { Player player; Enemy enemy; Boss boss;
public void start() // ゲーム開始時に一度だけ呼ばれる { player = new Player(); enemy = new Enemy(); boss = new Boss(); }
public void update() { if (KeyDown( A_BUTTON )) // Aボタンが押されていたら player.attackEnemy( enemy ); if (KeyDown( B_BUTTON )) // Aボタンが押されていたら player.attackBoss( boss ); } }
![Page 7: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/7.jpg)
クラス図Player は Enemy と Boss に依存してる
![Page 8: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/8.jpg)
依存の影響
![Page 9: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/9.jpg)
Open-Closed Principle
“オープン・クローズドの原則”
![Page 10: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/10.jpg)
敵を増やそうマジシャン、狂熊、ワルガキ 凶悪でかっこいいモンスターのアイデアがじゃぶじゃぶ湧き出る…!!
![Page 11: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/11.jpg)
Codeclass Player { public void attackEnemy(Enemy enemy) { enemy.damage( 10 ); } public void attackBoss(Boss boss) { boss.damage( 10 ); } public void attackMagician(Magician magician) { magician.damage( 10 ); } public void attackWarBear(WarBear warBear) { warBear.damage( 10 ); } public void attackBadBoy(BadBoy badBoy) { badBoy.damage( 10 ); } }
![Page 12: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/12.jpg)
クラス図Player はいろんな敵を知っている状態じゃないと成立しない
![Page 13: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/13.jpg)
依存を減らしたい
• Playerの他者への依存は膨らむばかり
• 依存をなんとか減らせないか
![Page 14: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/14.jpg)
共通のインターフェイス• クラスの持つべき性質をルール化する • 基底クラス
• C# の interface, C++なら多重継承
• Duck Typing
• ルールを決める手段は言語や処理系によって様々
• ルール:ダメージを受けることができる
![Page 15: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/15.jpg)
damage()
![Page 16: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/16.jpg)
Interface// ルールの規定 interface ILife { function damage(int value); }
// ルールに基づく実装 class Enemy implements ILife { var hp = 10; public function damage(int value) { hp -= value; } }
![Page 17: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/17.jpg)
Playerはシンプルにclass Player { // ILife インターフェイスを持つ相手ならだれでも public void attack(ILife target) { target.damage( 10 ); // damage()を与えちゃうよ } }
![Page 18: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/18.jpg)
敵がいくら増えてもclass Boss implements ILife { int hp = 100; public void damage(int value) { hp -= value/2; } }
class Magician implements ILife { int hp = 5; public void damage(int value) { hp -= value; } }
class BadBoy implements ILife { int hp = 99; public void damage(int value) { hp -= value; } }
![Page 19: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/19.jpg)
Playerは影響を受けないclass Player { // ILife インターフェイスを持つ相手ならだれでも public void attack(ILife target) { target.damage( 10 ); } }
![Page 20: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/20.jpg)
クラス図インターフェイスを知っていれば 具体的な相手は知らなくて良い
![Page 21: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/21.jpg)
良くなったこと• 意識することが減る
• 敵を作ったら damage っていう関数を必ず作って、Playerにその敵専用の攻撃メソッドを追加するの忘れないでね
• ILifeのインターフェイス実装しといて
![Page 22: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/22.jpg)
良くなったこと• コンパイル時間の低下
• 敵のロジック修正するたびにPlayerが再コンパイルされる
• 変更した敵のファイルだけ再コンパイルされる
![Page 23: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/23.jpg)
インターフェース• チーム開発、大規模開発において重要な考え方
• 技術仕様のコード化
• テストが書きやすくなる
![Page 24: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/24.jpg)
OCP• 拡張をしても、他のモジュールへ影響を与えない
• 新しい敵を追加しても Player は影響を受けない
• Player のロジックを変更しても敵は影響を受けない
![Page 25: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/25.jpg)
ちょっと寄り道class GameManager { Player player; Enemy enemy; // implements ILife Boss boss; // implements ILife
public void start() // ゲーム開始時に一度だけ呼ばれる { player = new Player(); enemy = new Enemy(); boss = new Boss(); }
public void update() // 毎フレーム呼ばれる { if (KeyDown( A_BUTTON )) // Aボタンが押されていたら player.attack( enemy ); if (KeyDown( B_BUTTON )) // Bボタンが押されていたら player.attack( boss ); } }
![Page 26: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/26.jpg)
こいつ何者?• 役割の明確でないクラス名
• インスタンスの生成・ゲームロジック・入力処理。なんでも屋。
• ゲームに出てくるクラスを全部知っているつまり、すべてのクラスに依存している
• 世界を知るもの
![Page 27: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/27.jpg)
依存注入とはDependency Injection
![Page 28: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/28.jpg)
新仕様
プレイヤーは武器を装備できて敵を攻撃できるんだよ
![Page 29: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/29.jpg)
Codeclass Weapon { public int power() { return 10; } // 攻撃力 }
class Player { public void attack( ILife enemy ) { Weapon weapon = new Weapon(); enemy.damage(weapon.power); } }
![Page 30: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/30.jpg)
新仕様
新しくて、かっこ良くて、強い武器が思いついてしまうんだ…!
![Page 31: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/31.jpg)
Interfaceinterface IWeapon { int power() // 攻撃力 }
class SuperSword implements IWeapon { public int power() { return 9999; } // 攻撃力 }
class BigGreatAxe implements IWeapon { public int power() { return 100; } // 攻撃力 }
class HyperUltimateKnife …
![Page 32: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/32.jpg)
Playerclass Player { IWeapon weapon;
public void equip( int type ) { switch(weaponType) { case 1: weapon = new SuperSword(); break; case 2: weapon = new BigGreatAxe(); break; case 3: weapon = new HyperUltimateKnife(); break; } }
public void attack( ILife enemy ) { enemy.damage( weapon.power() ); } }
![Page 33: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/33.jpg)
クラス図Playerがすべての武器に依存してるぞ…
![Page 34: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/34.jpg)
依存を絶つ
Player に誰かが武器を渡してあげる (Inject)
![Page 35: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/35.jpg)
依存注入のパターンclass Player { IWeapon equipedWeapon;
Player( IWeapon weapon ) { equipedWeapon = weapon; }
public void setWeapon( IWeapon weapon ) { equipedWeapon = weapon; }
public function attack( ILife enemy ) { enemy.damage( equipedWeapon.power() ); }
/* こんな書き方も */
public void setWeaponAndAttack( ILife enemy, IWeapon weapon ) { enemy.damage( weapon.power ); } }
![Page 36: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/36.jpg)
Constructor Injection Player( IWeapon weapon ) { equipedWeapon = weapon; }
![Page 37: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/37.jpg)
Setter Injection public void setWeapon( IWeapon weapon ) { equipedWeapon = weapon; }
![Page 38: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/38.jpg)
Interface Injectionpublic void setWeaponAndAttack( ILife enemy, IWeapon weapon ) { enemy.damage( weapon.power ); }
![Page 39: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/39.jpg)
クラス図Player は インターフェイスのみに依存
![Page 40: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/40.jpg)
また寄り道class GameManager { Player player; Enemy enemy; Boss boss; Weapon weapon;
public void start() // ゲーム開始時に一度だけ呼ばれる { weapon = new Weapon(); player = new Player( weapon ); // 依存の注入 Constructor Injection enemy = new Enemy(); boss = new Boss(); }
public void update() { if (KeyDown( A_BUTTON )) // Aボタンが押されていたら player.attack( enemy ); if (KeyDown( B_BUTTON )) // Bボタンが押されていたら player.attack( boss ); } }
![Page 41: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/41.jpg)
何が起きているか• Player はインターフェイスさえ知っていれば、どんな武器でも使いこなせるし、どんな敵にも攻撃できるようになった
• 敵をじゃぶじゃぶ追加できるようになった
• 武器をじゃぶじゃぶ追加できるようになった
• GameManagerという謎のクラスがすべての武器とすべての敵に依存している
![Page 42: Dependency Injectionとは](https://reader033.vdocuments.net/reader033/viewer/2022042716/55af7c541a28ab3c568b478a/html5/thumbnails/42.jpg)
次回DIコンテナについてやります