[Java] SpringのDIに「インターフェース」は必要?現場で使われる本当の理由

こんにちは。ゆうせいです。

「SpringのDI(依存性の注入)にはインターフェースが使われている」

Javaの勉強を進めていると、こんな噂を耳にすることはありませんか?

でも、実際にコードを書いていると、「あれ? インターフェースを作らなくても動くぞ?」と気づく鋭い方もいるかもしれません。

結論から言うと、「インターフェースは必須ではないけれど、活用したほうが圧倒的に便利で、プロっぽいコードになる」 というのが真実です。

今回は、なぜDIとインターフェースが相思相愛の関係にあるのか、そして現場ではどう活用されているのかを、身近な「コンセント」に例えて解説します。


噂の真相:インターフェースは必須?

まず、技術的な事実を整理しましょう。

今のSpring Framework(特にSpring Boot)では、インターフェースを作らなくてもDIは可能です。

クラス(具象クラス)に直接 @Autowired してDIすることはできますし、それでエラーになることもありません。

しかし、多くの技術書や現場のコードでは、あえてインターフェースを挟む設計が採用されています。

それはなぜか?

「部品の交換」を最高にスムーズにするため です。

「コンセント」で理解するインターフェースの役割

ここで、壁にある「コンセント」を想像してください。

コンセント(インターフェース)の役割

壁のコンセントには、ドライヤーも、スマホの充電器も、テレビも挿せますよね。

コンセント側は「2つの穴が開いているプラグなら、何が来ても電気を送るよ」というルール(契約) だけを決めています。

このルールこそが インターフェース です。

家電製品(実装クラス)の役割

一方で、ドライヤーやテレビは、そのルールに従って作られた 実装(中身) です。

DIとの関係

もし、壁から直接「ドライヤー専用のコード」が生えていたらどうでしょう?(これがインターフェースを使わない状態です)。

髪を乾かすにはいいですが、テレビが見たくなったら、壁工事をしてコードを取り替えなければなりません。これでは不便ですよね。

プログラミングも同じです。

「どんな処理が来るかわからないけど、とりあえずこのルール(メソッド)を持ったやつが来るよ」と決めておくことで、あとから中身(実装)を自由に入れ替えられるようになるのです。

コードで見る「交換のしやすさ」

具体的なコードで、インターフェースがある場合とない場合の違いを見てみましょう。

ここでは「通知(Notification)」を送る機能を考えます。

1. インターフェースを作る

まず、「メッセージを送る」というルールだけを決めたインターフェースを作ります。

public interface Notification {
    void send(String message);
}

2. 中身(実装)を作る

次に、そのルールに従って「メールで送る機能」を作ります。

@Component
public class EmailNotification implements Notification {
    @Override
    public void send(String message) {
        System.out.println("メールで送信: " + message);
    }
}

3. 使ってみる(DIする)

ここが重要です!

使う側のクラスでは、具体的な「EmailNotification」ではなく、インターフェースの「Notification」を受け取る ように書きます。

@Service
public class OrderService {
    
    private final Notification notification;

    // コンストラクタで「Notificationの仲間なら何でもいいよ」と待つ
    public OrderService(Notification notification) {
        this.notification = notification;
    }

    public void completeOrder() {
        notification.send("注文が完了しました");
    }
}

もし「LINEで送りたい」となったら?

仕様変更で「メールじゃなくてLINEにして」と言われたとします。

インターフェースを使っていれば、やることは2つだけです。

  1. LineNotification クラスを作る。
  2. 古い EmailNotification を捨てる(または @Component を外す)。

使う側の OrderService のコードは、1行も書き換える必要がありません!

なぜなら、OrderService は「Notification(コンセント)」を使っているだけで、その先につながっているのがメールなのかLINEなのかには興味がないからです。

これが、インターフェースを活用したDIの最大のメリットである 「疎結合(そけつごう)」 です。

現場でインターフェースを使う2つの理由

「交換なんてそんなにしないでしょ?」と思うかもしれません。

しかし、現場では以下の理由から頻繁にインターフェースが活用されます。

1. テストが圧倒的に楽になる

これが最強の理由です。

本物の「クレジットカード決済機能」を使ってテストをすると、毎回お金がかかってしまいますよね。

インターフェースを使っておけば、テストの時だけ「お金を払ったフリをするニセモノ(モック)」に差し替えることが簡単にできます。

OrderService はニセモノかどうかなんて気にせず動いてくれるので、安全にテストができるのです。

2. 開発を分担できる

Aさんは「使う側の OrderService」を、Bさんは「中身の EmailNotification」を担当するとします。

最初にインターフェース(ルール)さえ決めておけば、Bさんの中身が完成していなくても、Aさんは開発を進めることができます。

まとめ

今回の疑問への答えはこうです。

  • 本当か?→ 本当です。 Springの設計思想の根幹にはインターフェースがあります。
  • 必須か?→ 必須ではありません。 クラスそのままでもDIは動きます。
  • なぜ使うのか?→ 「部品の交換」や「テストのためのニセモノへの差し替え」を簡単にするためです。

最初は「ファイルが増えて面倒だな」と感じるかもしれません。

しかし、インターフェースを使いこなせると、変更に強く、テストもしやすい「壊れにくいシステム」を作れるようになります。

まずは、「インターフェース = 差し替え可能なコンセント」というイメージを持って、コードを読んでみてください。

きっと今まで見えなかったSpringの工夫が見えてくるはずですよ!

それでは、また次の記事でお会いしましょう。

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。