Dependency Injection

2020/09/01 03:50

「依存性の注入」とも言われるDependency Injection(DI)について動画でわかりやすく解説しています。実際にコードを使ってリファクタリングしながら理解する内容でお届けしました。クラスの外からインスタンスを渡す"差し替え可能性が高い柔軟なコード"にしていき、更にDIコンテナを利用すると「オブジェクトを生成して構築する部分をコードの中から排除できる事もある」というところまでをお伝えしています。15分弱の動画です。

はじめに

Dependency Injection(DI)について。 動画の内容はちょっと端折り過ぎていたと思うので、こちらで補足を入れたいと思います。

制御の反転(IoC)

本当はDIという言葉の前にIoC(Inversion of Control)という言葉を出した方が適切だと思うのですが咄嗟に言葉が出なくて落ちてしまいました。IoC自体は広い意味のある言葉の様子ですが、オブジェクトの生成と利用という点だけで考えると、

  • 「あるクラスのロジックの中で利用されるクラスが、そのクラスの中で生成される」という関係性が通常の制御構造
  • 「あるクラスのロジックの中で利用されるクラスが、そのクラスの外で生成される」という関係性を反転した制御構造

というイメージで理解できると思います。これは動画中で「設計パターンで言うDI」のような言葉で話しました(あとで調べるとDIパターンという言葉自体も大外しはしてないと受け止められている様子なので、それでもいいのかもしれませんが)。

また、より良いオブジェクト指向の設計を考える際に「インターフェースに対してコードを書く」という考え方があり、この考え方に従うと「コンストラクタ等で、あるインターフェースを実装したクラスを渡す事で、ロジックを柔軟に差し替えられるようになる」というような結果が生まれます。

差し替え可能性が上がる事で、自動テストが書きやすくなったり、仕様変更に対応しやすくなるなどの、柔軟性が生まれます。この考え方はDIコンテナという言葉が広がる前から既に存在していました。

歴史

昔はシステム開発の概念がエンタープライズなJavaの開発から広まる事が多かったのもあり、以下のような出自だと思います(おじさん達が喜ぶ話)。

  • 多くの現場では EJB(Enterprise Java Beans)での開発をしていました。ネットワークを介した分散環境の仕組みなどが入っているプラットホームで、かなり開発が重いという欠点がありました。コンパイルからデプロイまでにかなり時間もかかったのを話者も覚えています。オブジェクトの取得にServiceLocaterが使われていました(ServiceLocaterを利用すると、抽象的なオブジェクトを必要な時に探してきて取り出して利用する、というコードになる。ServiceLocater用のコードが入るのでServiceLocaterに依存します)。
  • EJB開発で重かったので、軽量コンテナとしてのDIコンテナが登場しました。一般のクラス(POJO)にできるクラスが増えたので(業務ロジックの部分をPOJOにできるイメージです)、開発が加速できて良いだろうという受け入れ方だったと思います。
  • このあと、EJBから離れてDIコンテナの概念はいろいろなところへ受け継がれて行きます

多分上記のような話はある程度長く働いてきた人達しか知らないですし、別に知らなくても現在DIコンテナのメリットを理解するのには不要だと話者は考えています。

エンタープライズなJava開発から離れて

例えば以下のようなところで見られるようにもなりました。

  • AngularJSで利用される
  • Laravelの中で利用される
  • (話者が知らないところでたくさん使われているはず...)

一旦これくらいでキーを叩くのをやめますが、DIの動画があまりによく見られているのでこのような補足を用意したくなりました。参考になれば幸いです。古い記憶も頼りに書いている部分があるので、もしも間違っていそうなところがあったら優しく指摘してくれると助かります。

解説に使用したコード

https://github.com/CircleAround/pgonline/blob/master/src/20200623_di.ts

この記事を書いた人

佐藤 正志

サークルアラウンド株式会社 代表取締役