定義から理解するDI ― 「依存性」が表す本当の意味

カサレアルで主にJava系のコースを担当している李です。

Spring FrameworkやSpring Bootを学ぶ時に避けて通れない概念として、Dependency InjectionDI)があります。日本では「依存性の注入」という訳語で知られています。

この記事では、以下の内容を通じて、DIが本来意味する「依存物の注入」の観点からDIを説明します。DIと言われてどんなコードを書くかは分かるが、いざ仕組みなどを説明しようとするとしっくり来ない人は、ぜひ読んでみてください。

  • DIを広めた論文の紹介
  • Spring FrameworkにおけるDIの実現方法
  • DIと「依存性の注入」定着に関する考察

    ※本記事内の英語文献からの引用は、別途補足がない限り筆者による訳文です

    目次

    「依存性の注入」では伝わらないDIの意味合い

    現在、DIの訳語として「依存性の注入」が定着しています。しかし、この訳語では、注入しているものと注入先がイメージしづらいという難点があります。

    私が今まで話した受講者および同業者も例外ではありません。実際にあったコメントがこちらです。

    • DIが注入する「依存性」って何でしょうか?依存性質?それとも注入のされ方が何かに依存している、ということでしょうか?
    • DIと言われて最初は理解ができず、実装内容を学習してイメージはできました。ただ、「依存性の注入」という言葉は後で知ったものの、自分が持っているDIのイメージにはつながりませんでした
    • 「注入」する先はDIコンテナで、DIコンテナに依存性を一任する形になるので「依存性の注入」と言うのかと思っていました。(中略)実際に使うようになり、「DIコンテナに注入する」ではなく、「DIコンテナから利用先に注入する」という表現が正しいと知って、「意味が逆では?」と少し混乱しました

    これらのコメントから垣間見えるのは、用語がむしろ概念の理解を妨げているとも言える状況です。

    以降の節では、DIを広めた論文およびSpring Frameworkのリファレンスの原文を確認し、DIが当初から「依存物の注入」という意味合いを持っていた事実を紐解きます。

    論文におけるDI

    DIは、マーチン・ファウラーが2004年1月に公開した論文「Inversion of Control Containers and the Dependency Injection Pattern」によって広められた用語だとされています。前述のとおり、日本では一般的に「依存性(の)注入」と訳されます。

    まず、ファウラーの論文におけるDIの説明を確認してみましょう。

    The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface[.]

     

    Dependency Injectionの基本的な考えは、〔例示にある〕リスト生成を行うクラス〔lister class〕のフィールドに、適切な捜索インタフェース〔finder interface〕の実装クラスを格納してくれる個別のオブジェクト(組み立て役 〔assembler〕)を用意することにある。

     

     

     

     

     

    (論文に掲載された図解。図は筆者にて再構成)

    上の説明と図解に登場するクラスとインタフェースの関係をまとめます。

    • リスト生成クラスMovieLister
      • リストに入れるべき要素を取得する方法が必要である
    • 捜索インタフェースMovieFinder、実装クラス名MovieFinderImpl
      • リストに入れるべき要素を取得する機能を持っている
    • 組み立て役オブジェクトAssembler
      • 捜索インタフェースの実装クラスのオブジェクトを生成し、リスト生成クラスのフィールドに格納する役割を果たす

    リスト生成クラスが正常に動作するためには、捜索インタフェース(を実装したクラスのオブジェクト)が必要です。言い換えると「リスト生成クラスの機能は捜索インタフェースの機能に依存している」状態です。

    また「組み立て役オブジェクト」の役割は、とあるクラス(例:リスト生成クラス)が依存しているオブジェクト(例:捜索インタフェースの実装クラスのオブジェクト)を、当該クラスのフィールドに格納することだと理解できます。

    つまり、DIを簡潔に説明すると、「オブジェクトBの機能に依存しているオブジェクトAに対して、オブジェクトBそのものを注入すること」と言えます。

    ※ファウラーの論文にあるIoC(Inversion of Control:制御の反転)への言及と、DIの方法(コンストラクタ注入、Setter注入、インタフェース注入)に関する記述については説明を省きます。

    Spring FrameworkにおけるDI

    Spring Frameworkのバージョン1.0は、ファウラーの論文とほぼ同時期の2004年3月にリリースされました。ファウラーの論文にも「様々な層からのコンポーネントを組み立てる」DI用コンテナの一例として言及されています。

    Spring Frameworkは「DIコンテナ」という「組み立て役オブジェクト」を利用してDIを実現しています。

    DIコンテナ

    DIコンテナは、アプリケーションの構成要素(コンポーネント)のオブジェクトを生成・管理する役割を持っています。DIコンテナがアプリケーションの構成要素をオブジェクト生成する際に、その構成要素が依存する別のクラスのオブジェクトを注入することでDIを実現しています。

    つまり、「依存物を注入する」役割を持つDIコンテナは、ファウラーの論文における「組み立て役オブジェクト」に当てはまります。Spring FrameworkのリファレンスにあるDIの説明も、ファウラーの論文の記述を想起させる内容になっています。

    Dependency injection (DI) is a specialized form of IoC, whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance [. . . .] The [DI] container then injects those dependencies when it creates the bean.

     

    Dependency Injection (DI) は、オブジェクトが自身の依存物(すなわち、利用される他のオブジェクト)をコンストラクタの引数やファクトリーメソッドの引数、またはインスタンスに付与されたプロパティ〔中略〕経由のみで定義する、IoCの特化した形態である。その後、〔DI〕コンテナはBean生成時に依存物を注入する。

    DIを「依存物の注入」と捉えよう

    以上の内容を踏まえ、私は「依存物の注入」がDIの適切な和訳だと考えています。DIという用語には一貫して「依存物を注入する」という説明が添えられているからです。

    2004年は、DIと「依存性の注入」両方とも広まった年

    現状として「依存性の注入」という和訳が定着していますが、2004年当時のWebページを確認すると、DIと「依存性(の)注入」がほぼ同時期に広まった様子が窺えます。

    「依存性注入」という訳語は、ファウラー論文公開の2ヵ月後である3月に公開された、角谷信太郎氏による同論文の和訳に登場しています。

    角谷信太郎氏の日本語訳を皮切りに、2004年の複数の記事に「依存性注入」という訳語を用いてDIに言及するケースが見られます。

    また、2006年にはWikipediaに「依存性の注入」記事が新規作成されましたが、和訳に関する補足はありませんでした。2004年以降、DIとほぼ同時に「依存性(の)注入」という訳語が広まった影響かと思われます。

    数年が経った2009年2月、角谷氏は自身のファウラー論文ページを更新し、「依存性注入」という訳を「依存オブジェクト注入」に訂正しています(翻訳記事下段の履歴参照)。しかし、この時点ですでに「依存性(の)注入」が定着しており、今に至ると推測されます。

    ※Wikipediaの「依存性の注入」ページには2022年9月3日に「依存オブジェクト注入」の記述が加筆されました。

    関連年表

    まとめ

    この記事では、DIが「依存物の注入」を意味していることをお伝えしました。DIの理解への助けになれば幸いです。

    • 英語文献の記述によると、DIは一貫して「依存物の注入」という意味合いを持っている
    • DIという用語はファウラーの論文をきっかけに、2004年以降広まった
    • Spring Frameworkでは、DIコンテナでDIを実現している
    • 「依存性の注入」という訳語は、ファウラーの論文とほぼ同時期に広まった可能性がある
    --------------------------
    開発支援・技術研修のご要望・ご相談はこちらから
    --------------------------
    【この技術ブログを読んだエンジニアの皆様へ】
    カサレアルブログをお読みいただき、ありがとうございます!

    私たちは、常に新しい技術に挑戦し、ユーザーのニーズに応えるサービスを提供しています。
    もし、当社の技術への情熱や、会社・チーム・社員の雰囲気に共感いただけたなら、
    ぜひ私たちと一緒に働きませんか?
    現在、株式会社カサレアルでは事業拡大に伴い、新たな仲間となるエンジニアを積極的に募集しています。

    少しでも興味をお持ちいただけましたら、まずは弊社のことを知っていただけると嬉しいです。
    ▼採用サイト
    https://www.casareal.co.jp/recruit/career
    ▼社員インタビュー
    https://hrmos.co/pages/casareal/jobs/0000016
    ▼エンジニアの仲間になる! エントリーはこちらから
    https://hrmos.co/pages/casareal/jobs

    皆様のエントリーを心よりお待ちしています!

    REST API と GraphQL の違い

    コメントを残す

    メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

    コメント ※

    名前 ※

    メール ※

    サイト