依存性の注入(Dependency Injection、DI)は、概念的で初心者が理解するにはハードルは高めです。
ただ、実態として意味するところはシンプルであり、「何をすることか?」「何故それをするのか?メリットは?」という点をピンポイントで押さえれば難しい概念ではありません。
今回は、そういった背景を整理するために、シンプルに解説をしてみたいと思います。
◇目次
「依存性の注入」とは、「依存性の注入」パターンを満たすようにプログラムを書くこと
「依存性の注入」と書くと注入する行為そのものを指すように感じさせますが、実態的には「依存性の注入」パターンを満たすようにプログラムを書くことを指すと捉えたほうが分かりやすいです。
より具体的には、次のようにソースコードを書くことを言います。
- とあるクラスAの中で、他のとあるクラスBのインスタンスを生成しない。
- クラスAの中でクラスBが必要であれば、クラスAの中で生成せずメソッドの引数で与える。その時は、実体クラスBではなくインターフェースの形式にする。
具体的にコードに起こすと次のようになります。
//「依存性の注入」パターンを満たすように書かれたプログラムの例
//クラスAの実装。Hogeメソッドの引数がインターフェースであることがポイント。
class ClassA {
public bool Hoge(IClassB classB) {
return classB.Fuga();
}
}
//引数とするインターフェース
interface IClassB {
bool Fuga();
}
「依存性の注入」パターンを満たすと、実体クラスに依存しないコードとなり、変更やテストが効率化する
「依存性の注入」パターンを満たすと、インターフェースを実装した別物の実体クラスに引数をすり替えてメソッドを実行できます。
これにより、引数インスタンスのプロパティ値やメソッドの戻り値を固定化したり、パターンテスト出来たりできます。
//①「依存性の注入」パターンを満たし、実体クラスBに依存しないメソッド。
//引数はインターフェースで指定。
public void Hoge(IClassB classB) { }
//②実体クラスBに依存するメソッド。「依存性の注入」のパターンではない。
//引数の型がインターフェースではなく実態クラスであることがポイント。
public void Hoge(ClassB classB) { }
上記2つの実装において、実際に使うものはいずれもClassBだとしても、①の書き方=依存性注入を満たす書き方であれば、インターフェースIClassBを実装する別のクラスに置き換えて実行することが可能です。
極端な話、インターフェースIClassBに定義されたメソッドやプロパティだけ持つ空っぽなクラスのインスタンスでも引数にして実行することが出来るのです。
この工夫によって次のようなメリットが生じます。
- ClassBが削除されたり変更されたりしても、メソッドに影響を及ぼさない実装となる。
- メソッドの単体テストが容易になる(メソッドテスト時に、実体クラスBのバグの影響を排除できる。)
尚、単体テストが容易になるという点については、例えば次のコード例のようにメソッドの戻り値などを固定値に置き換えたインターフェース実装クラスに置き換えてテストすることによって発揮されます。
実体クラスClassBが自チームで開発しているクラスであればまだ制御しやすいですが、例えばコミュニティ開発のフレームワーク内のクラスなどであれば、いつ変更が入るかも分かりません。なので尚更DIに沿った実装が求められるのです。
//テスト用クラス。
//メソッドの戻り値などを固定して、クラスB側でのバグ影響を排除。
class ClassBForTest : IClassB {
public bool Hoge() {
return true;
}
}
//実装クラス。テストには使用しない。
class ClassB : IClassB {
public bool Hoge() {
//複雑な処理
}
}
「依存性の注入」は、保守性が高いソフトウェアの開発には必須知識
以上の通り、「依存性の注入」は関心の分離(Separation of Concerns、SoC)実現のため疎結合化を行うプログラミング技法です。
例えば多くのオープンソースソフトウェアなどで実際に採用されており、保守性の高いコードを作成するためにはもはや必須知識といえます。
また、DIをも含む「関心の分離」の考え方は、変更やテストに強い保守性の高いコードを作る為に重要な考え方です。関連記事に詳細を記載していますので、是非あわせてご参考いただき理解が進めば嬉しく思います。
今回は以上です。ありがとうございました。
記事筆者へのお問い合わせ、仕事のご依頼
当社では、IT活用をはじめ、業務効率化やM&A、管理会計など幅広い分野でコンサルティング事業・IT開発事業を行っております。
この記事をご覧になり、もし相談してみたい点などがあれば、ぜひ問い合わせフォームまでご連絡ください。
皆様のご投稿をお待ちしております。