はじめに
特に転職してからSpringBootのフレームワークを用いた開発を2-3年ほど続けてきて、Springの理解はだんだん深くなってきて、ソースもすいすいと読めるようになってきました。
ですが、いざDIとか何が嬉しいんですか?と聞かれると明確に答えられないなと思い、これを機に一度基本から考えてみることにしました。
色々考えていて、SpringBootを使う利点がよくわからなくなってしまいました・・・お恥ずかしい・・・
コメントなどでこういう場合とか、理解が間違っているなど教えていただきたいです。
DIコンテナ
とりあえず、真っ先にDIコンテナとかIoCコンテナがSpringだったらいい点として挙げられますよね。
自分の理解だと、呼び出す側が呼び出す方の実装に依存しちゃうのを防げるのがいい点だと理解していて、よくリポジトリ層とかで実装が変えたときの変更可用性が高いってのが挙げられると思っています。そんな変更ほとんどしたことないけど。
// Oracle -> MySQLに変更するときに変更が発生する
class SampleService(){
val sampleRepository = OracleSampleRepository()
fun find(hogeId: String): hogeModel{
return sampleRepository.find(hogeId)
}
}
Springだとどうなるか
@Service
class SampleService(
val sampleRepository: OracleSampleRepository // ここを変更すれば大丈夫
){
fun find(hogeId: String): hogeModel{
return sampleRepository.find(hogeId)
}
}
あれ、結局そんなに手間変わらんのでは・・・
理論上、後者の方がきれいなのは分かるんですが実装したときに結局注入するクラスを変更しなきゃいけないし手間変わらなくね・・・?という気がしてきました。
MySQLSampleRepository
みたいなクラスを作って、メソッドと引数を同じにしておけば結局書き換える手間としては同じような。
同じメソッドを使うのを強制させたいなら適当なSampleRepositoryInterface
みたいなクラスをつくってあげれば強制もできるし、実際DIコンテナを使用するメリットがよくわからなくなってきてきました。。
その他便利かも?と思うユースケースを考えてみる
テストしやすい
コンストラクタインジェクションしているところに、テストコードだとmockをいれてあげればいいのでテストしやすいです。
が、使わなくても引数にinterfaceをもらうことにすれば解決できそうな気がします。
class SampleService(
sampleRepository: SampleRepositoryInterface
){
fun find(hogeId: String): hogeModel{
return sampleRepository.find(hogeId)
}
}
ただ、こうしてしまうとSampleService
を呼び出す側でSampleRepositoryImpl
の実装を意識しないといけなくなりますね。
class SampleServiceImpl: SampleServiceInterface(
sampleRepository: SampleRepositoryImpl
){
override fun find(hogeId: String): hogeModel{
return sampleRepository.find(hogeId)
}
}
これを回避するにはService
にもinterfaceを用意してあげればよさそうだけど、正直めんどくさい。
テストしやすいのと、変更しやすいを両立しているのは確かにSpringを使うメリットとして挙げてよい気がします。
application.yaml
から設定値を引っ張ってこれる
これはたしかに便利ですが、正直DIコンテナじゃなくてもよくて、起動時に適当なファイルから読み込んで定数としてもっちゃえば解決できそうです。
SpringSecurityなどの認証認可の仕組みが自前で作らなくても使える
SpringSecurityに限らず、色々機能が豊富でやりたいことはライブラリ使えばできるのはたしかにメリットですね。
だいたいみんな知ってる
処理の流れとか説明しなくても、Controller
のクラスからたどる〜とか、Bean
はデフォルトでシングルトンだから気をつけようね〜みたいなことは説明不要。おまけにググったらいろいろ文献でてくる。
これもメリットですね。
まとめ
自分で色々考えた結果、SpringBoot
を使うメリットとしては以下なのかなという風に思いました。
- 面倒なことをせずにテストしやすいコードを書ける
- Springの付随する機能を簡単に使うことができる
- 使用者が多いため、文献が多い
DIが手軽に実現できて超嬉しい!と結局納得できるようなメリットが考えられなかったので、冒頭にも書きましたがコメントなのでやさしく教えていただけると大変うれしいです