📚 目次
Javaにおける依存関係とは?
Javaを使い始めてから5年。「依存関係」「依存性の注入」という言葉をよく耳にしていたんですけど無意識に受け流していました…。
最近、職場(プロジェクト)が変わりアプリ基盤チームに移ったことで改めて勉強しようと思うきっかけがあったので簡単な内容をまとめました。
理解が不安な人や、最近Javaを勉強し始めた人の役に少しでも立てたら嬉しいです!
1. 依存関係って何?
依存関係(Dependency) とは、あるクラスやモジュールが、他のクラスやモジュールを利用する関係のことです。
簡単に言うと、「AクラスがBクラスに頼って動いている状態」です。
たとえば次の例では、UserService
クラスが UserRepository
クラスに依存しています:
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findUserById(String userId) {
return userRepository.findById(userId);
}
}
このコードでは、UserService
クラスが UserRepository
クラスに依存しています。
もし UserRepository がなければ、UserService
は動きませんよね。これが依存関係です。
( UserService
がなくても UserRepository
は動きます)
2. なぜ依存関係が重要なのか?
依存関係を理解する上で「なぜ使うのか?」
はとても大事な考え方です!
メリットを理解しましょう。
依存関係を理解することで、以下のような課題を解決できます。
2.1 再利用性の向上
適切に依存関係を管理すると、コードの再利用性が高まります。
例えば、UserRepository
を他のクラスでも簡単に使えるようになります。
2.2 テストが簡単に
依存関係を明示すると、ユニットテストでモック(偽のオブジェクト)を使いやすくなります。
モックの使い方については、仕事で出会ったら調べてみてください。
// テスト用コード
@Test
void testFindUserById() {
// テスト用のMockを生成
UserRepository mockRepository = mock(UserRepository.class);
when(mockRepository.findById("123")).thenReturn(new User("123", "John Doe"));
UserService userService = new UserService(mockRepository);
User user = userService.findUserById("123");
assertEquals("John Doe", user.getName());
}
3. 依存関係を管理する3つの方法
3.1 クラス内で直接作る方法(普通にimportして使う参考書とかに書いてあるプログラム)
クラスの中で依存するオブジェクトを自分で作る方法です。
public class UserService {
private UserRepository userRepository = new UserRepository();
}
メリット
- 簡単に書ける
- 小さいプログラムなら問題なし
デメリット
- テストが難しい(
UserRepository
を差し替えられない) - 他の実装に変更しづらい
3.2 コンストラクタ注入
依存するオブジェクトをコンストラクタで渡してもらう方法です。
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
メリット
- テストがしやすい(簡単にモックオブジェクトを渡せる)
- 他の実装に変更しやすい
デメリット
- コンストラクタで渡す必要があるので、少し手間
3.3 フレームワークを使う方法 ※DI(依存性注入)
Springなどのフレームワークを使えば、依存関係を自動で注入してくれます。
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
メリット
- 依存関係の設定が簡単になる
- 大きなプロジェクトでも効率的
デメリット
- フレームワークの学習が必要
- 小さいプログラムにはオーバーエンジニアリングになる場合も
まとめ
- 依存関係 とは、クラスやモジュール間の「頼り合い」のこと
- 適切に依存関係を管理することで、コードの再利用性やテスト容易性が向上
- 手動管理からフレームワーク活用まで、目的に応じて使い分けるのがポイント
次回は「依存性の注入」について書きます。