[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つだけです。
LineNotificationクラスを作る。- 古い
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年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。