1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java】DIとは何か (備忘録)

Last updated at Posted at 2024-11-06

はじめに

今回はJavaを学習した中で出会ったDI(dependency Injection)について記事を書いていきます。

DI(dependency Injection)とは

DI(Dependency Injection)とは、クラス同士の結合度を低くする設計思想を指します。ここで述べる結合度とは、クラスAがクラスBに対してどれだけ依存しているかを表す概念です。

結合度が高い状態とは、クラスAがクラスBを呼び出すときに、クラスBのインスタンス(オブジェクト)を毎回生成して利用する状態を指します。この場合、クラスAはクラスBがなければ動作できません。そのため、クラスBに変更があった場合、クラスAにも大きな影響を及ぼします。

一方、DIを用いて結合度が低い状態とは、クラスAがクラスBを呼び出す際に、一度クラスCを経由することです。クラスCを介入させることで、クラスAとクラスBは独立した状態で動作できるようになります。これにより、いずれかのクラスに変更があった場合でも、影響を最小限に抑えることが可能となります。

例えるなら

DIの概念をわかりやすくするために、スマートホームとアシスタントAIを用いて説明します。

AIアシスタントが備わったスマートホームを想像してください。家には既にAlexというサービスと直接契約してます。しかし途中から利用するAIを変更したくなりました。ですがAlexにすべてを任せていたため、簡単に変更ができなくなっています。

上記のたとえ話の中でDIを適用した状態とは、利用者とAIサービスの間に中間業者を入れた状態です。
これから利用者は中間業者とやり取りすることになります。この状態なら、中間業者が各サービスを上手に調整してくれるので、サービスを変更しても大きな影響がありません。

プログラム例

DIを利用したプログラムを以下に示します。

メインクラスはそれぞれのAIを備えたスマートホームです。
コード中の⓵の部分が利用するAIの宣言。コード中⓶の部分がAIを利用するサービスを宣言します。
コード⓶では利用したいAIを中間業者に渡しています。
中間クラスがAIを利用できる状態にし、コード⓷ではAIを利用できるようにしています。

メインクラス
import AssistantAI.Alex;
import AssistantAI.Assistant;
import AssistantAI.Siro;

public class Main {

	public static void main(String[] args) {
		// Alexを利用したスマートホーム
		Assistant Alex = new Alex();         //・・・⓵
		Service Service1 = new Service(Alex);//・・・⓶
		Service1.Hello();                    //・・・⓷
		
		System.out.println();
		
		// Siroを利用したスマートホーム
		Assistant Siro = new Siro();
		Service Service2 = new Service(Siro);		
		Service2.Hello();
		
	}

}

以下はスマートホームで利用するAIのクラスです。
メインからAIクラスは呼び出さず中間クラスを経由します。

AIクラス
package AssistantAI;

public interface Assistant {
    void greeting();
}

package AssistantAI;

public class Alex implements Assistant {

    @Override
    public void Greeting() {
        System.out.println("こんにちは。私は Alex です。");
        System.out.println("Riverから生まれました。");
    }
}

package AssistantAI;

public class Siro implements Assistant {

    @Override
    public void greeting() {
        System.out.println("こんにちは。私は Siro です。");
        System.out.println("Fruitから生まれました。");
    }
}

以下はメインクラスにAIクラスを渡すための中間クラスです。中間クラスがメインクラスの代わりにAIクラスをオブジェクト化します。メインクラスはオブジェクト化したものを扱います。

中間クラス
import AssistantAI.Assistant;

public class Service {
	private Assistant AssistantAI;
	
	public Service(Assistant AssistantAI) {
		this.AssistantAI=AssistantAI;
	}
	
	public void Hello() {
		AssistantAI.Greeting();
	}
	
}

メインクラスを実行すると以下の結果が得られます。中間クラスがメインクラスとAIクラスの間に入ってオブジェクトのやり取りをするので利用するAIクラスを変更しても動きます。

Result
こんにちは。私は Alex です。
Riverから生まれました。

こんにちは。私は Siro です。
Fruitから生まれました。

おわりに

以上からDIを簡単にまとめると次の通りになります。

  • オブジェクトを関節的にやり取りすること
  • それぞれのクラスが独立していること
  • クラスの修正がしやすいこと

以上がDIに対する私の認識でした。誤り等あればご指摘ください。

参考文献

  • Dependency Injection :: Spring Framework

  • 土岐孝平 著, "プロになるためのSpring入門 ――ゼロからの開発力養成講座",
    技術評論社, pp.38-47
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?