0
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?

More than 5 years have passed since last update.

ことりんと一緒 Springもね - 7. サービス層

Last updated at Posted at 2019-01-19

概要 / 説明

Kotlinでサーバーサイドアプリケーションを作ってきましたが、まだきちんとした構成にはなっていない状態です。
ことりんと一緒 Springもね - 2. RestController と Data Class」 でコントローラクラスを作り、直接データを扱うような構成のままです。
そこで、少しずつ変更を行っていきます。
まず、ここでは「サービス」層を考えていきます。

service-layer.png

Webアプリケーションでは大きく分けて次のような機能が必要となります。

  • リクエスト/レスポンスの処理
  • アプリケーションロジックの処理
  • データの処理

今まではこれらの機能を単一レイヤで担当していました。
このままの構成だと、扱うロジックが増え、データモデルが複雑になってくると、
1つのクラスが巨大になり開発/保守効率が悪くなってしまいます。

それぞれの機能を分離して、複数のレイヤに分けていきます。

さて、作っていたクラスが RestController ということで、
本来はリクエスト/レスポンスを扱うことを責務とします。
そこで、それ以外の処理を切り出し、それを サービス とします。

前提 / 環境

ランタイムバージョン

  • Kotlin : 1.3.0
  • SpringBoot : 2.1.0.RELEASE

Spring Dependencies

  • Web
  • Actuator

開発環境

  • OS : Mac
  • IDE : IntelliJ IDEA
  • Build : Gradle

手順 / 解説

変更前のコントローラクラス

元々は以下のようにコントローラクラスの中でデータの生成など、リクエスト/レスポンスの処理以外のことを行っていました。

@RestController
@RequestMapping("/messages")
class SimpleController {

    @GetMapping
    fun getMessages() : List<Message> {
        return listOf(
                Message(
                        UUID.randomUUID().toString(),
                        "First Message",
                        "This is a 1st message on ${getDate()}."
                ),
                Message(UUID.randomUUID().toString(),
                        "Second Message",
                        "This is a 2nd message on ${getDate()}."
                )
        )
    }

    private fun getDate() : String {
        val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
        return simpleDateFormat.format(Date())
    }
}

サービスクラス

元々コントローラクラスに実装していた内容を以下のようにサービスクラスに移します。

@Service("Message Service")
class MessageService {

    fun getMessages() : List<Message> {
        return listOf(
                Message(
                        UUID.randomUUID().toString(),
                        "First Message",
                        "This is a 1st message on ${getDate()}."
                ),
                Message(UUID.randomUUID().toString(),
                        "Second Message",
                        "This is a 2nd message on ${getDate()}."
                )
        )
    }

    private fun getDate() : String {
        val simpleDateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
        return simpleDateFormat.format(Date())
    }
}

サービスクラスには @Service アノテーションを付与します。
これによりコントローラクラスの中で Dependency Injection により利用できるようになります。

@Autowired
private lateinit var service: MessageService

lateinit キーワードは、インスタンスを初期化せずに宣言するときに使用します。

変更後のコントローラクラス

サービスクラスを使用するコントローラクラスでは、リクエスト/レスポンスに関する処理だけを担当するようにします。
以下のようにサービスクラスで実装している処理を呼び出すように変更を行います。

@RestController
@RequestMapping("/messages")
class MessageController() {

    @Autowired
    private lateinit var service: MessageService

    @GetMapping
    fun getMessages() = service.getMessages()
}

まとめ / 振り返り

責務ごとにレイヤを分けてアプリケーションを開発するのことは、今や定石ですね。
まだ、この状態ではサービスレイヤからデータ処理を直接行うようになっているので、
次はその部分を分離していきます。

今回のソース

0
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
0
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?