Upgrade to Pro — share decks privately, control downloads, hide ads and more …

依存性逆転ってなんですか

 依存性逆転ってなんですか

依存性逆転の原則ってなんですか
どうしてそれが大事なんですか

こんな人向け
・プログラミングを始めて2,3年以上
・オブジェクト指向でプログラミングをしている
・依存性逆転という言葉を聞いたことがあったり、依存性逆転の原則を守らなければならないとか言われるがよくわからない
・「依存性注入ってなんですか」のスライドを見た
 https://speakerdeck.com/akikogoto/yi-cun-xing-zhu-ru-tutenandesuka-dousitesoregada-shi-nandesuka

Avatar for Goto Akiko

Goto Akiko

May 24, 2026

More Decks by Goto Akiko

Other Decks in Programming

Transcript

  1. 2 自己紹介 • 株式会社オンラインコンサルタント 代表取締役 • プログラミング歴は19年 • 受託開発・自社サービスなど多数の開発 •

    メインの実績は3000社以上の導入実績がある 「ODIN リアルタイム配送システム」 という配送会社向けのシステム https://delivery-system.com/ @Akiko_Goto999
  2. 9 復習 依存とは コードはTypeScriptで書いていきます。 // 前回のスライドでも使った味噌汁を作るクラス class MisoSoup { seasoning

    : Miso // 味は味噌 ingredient : Tofu // 具材は豆腐 constructor(seasoning: Miso, ingredient: Tofu) { this.seasoning = seasoning; this.ingredient = ingredient; } } このMisoSoupクラスは Misoクラスと Tofuクラスに 「依存している」 と言います。 // エントリーポイント const miso_soup = new MisoSoup(new Miso("赤味噌", "濃厚"), new Tofu("絹ごし", "なめらか"))
  3. 10 しかし // 味噌汁を作るクラス class MisoSoup { seasoning : Miso

    // 味は味噌 ingredient : Tofu // 具材は豆腐 constructor(seasoning: Miso, ingredient: Tofu) { this.seasoning = seasoning; this.ingredient = ingredient; } } MisoSoupクラスが 味噌に依存しているのは ともかく、 このままだとTofuクラスに 依存しているので、ずっと 具は豆腐しか選べない。 他の具材を選びたい 時が来るはず。
  4. 11 Tofu クラスに依存しないようにする① // 具材全般を表すインターフェースを作成 interface Ingredient { name :

    string } class Tofu implements Ingredient { name : string texture : string constructor(name: string, texture: string) { this.name = name; this.texture = texture; } } MisoSoupクラスが Tofuクラスに 依存しないようにする ための準備。 まずインターフェースを 作って、依存したくない クラス (ここではTofuクラス)に implementsする。 ポイント!
  5. 12 Tofu クラスに依存しないようにする② class MisoSoup { seasoning : Miso ingredient

    : Ingredient constructor(seasoning: Miso, ingredient: Ingredient) { this.seasoning = seasoning; this.ingredient = ingredient; } getIngredient(): string{ return this.ingredient.name; } } そして、MisoSoupクラスに 渡す時は そのインターフェースを使う。 ポイント!
  6. 15 インターフェースにすることで 大きな違いが出る class MisoSoup { seasoning : Miso ingredient

    : Ingredient constructor(seasoning: Miso, ingredient: Ingredient) { this.seasoning = seasoning; this.ingredient = ingredient; } getIngredient(): string{ return this.ingredient.name; } } 具材を変更しても、 MisoSoupクラスに 何の変更も 加えなくてよい! // MisoSoupの具材をネギに変更する例 // Ingredientインターフェースを継承した // Negi クラスを新しく作る class Negi implements Ingredient { name : string texture : string constructor(name: string, texture: string) { this.name = name; this.texture = texture; } } // エントリーポイント const miso_soup = new MisoSoup(new Miso(“赤味噌”, “濃厚”), new Negi(“長ネギ”, “シャキシャキ"))
  7. 19 例: DB アクセス class UserRepository{ getUser():User{ // DBにアクセスし複雑なユーザー //クラスを組み立てて返す処理

    } } class GreetUser{ greet(repository:UserRepository):String{ return "Hello, " + repository.getUser().name + "!"; } } 例えばこんなコードだと、 GreetUser.greetのテストを作る 場合にDBアクセスが発生する。 次のような問題がある。 ・DBからデータを取得すること に時間がかかる ・DBにデータを用意しなければ ならない ・テストの独立性が損なわれる
  8. 21 例: DB アクセス をモック(偽物)に置き換える interface Repository { getUser():User }

    export class UserRepository implements Repository { getUser():User{ // DBにアクセスし複雑なユーザー //クラスを組み立てて返す処理 } } export class MockUserRepository implements Repository { getUser():User{ // テスト用のモックデータを返す return new User("Bob", 25); } } 一旦インターフェースに することにより、 テスト用のモックを作る ことが簡単になる。 class GreetUser{ greet(repository:Repository):String{ return "Hello, " + repository.getUser().name + "!"; } } 引数の型がRepositoryだから UserRepositoryもMockUserRepository でも大丈夫