本文へスキップ
BecomeCoder

Java MVVMコース · 第5章 Service ― 業務ロジックの層 · レッスン17

Serviceとは何か ― Repositoryとの違い

ローカル実施

導入

TaskRepositoryTaskItemをそのまま出し入れするだけで、中身の状態(完了かどうか、タイトルが重複していないか)には関心がありません。「未完了だけを見せる」「同じタイトルは禁止する」といった判断は、Repositoryではなく別の層が持つべきです。この判断を担当するのがTaskServiceです。

説明

flowchart LR
    VM["ViewModel(画面の状態)"] --> SVC["TaskService<br/>業務ルール・判断"]
    SVC --> REPO["TaskRepository<br/>データの出し入れだけ"]
    REPO -.-> MEM["InMemoryTaskRepository"]
    style SVC fill:#e1f5fe

役割の違いをコードで見ます。

// Repository: 「そのまま出し入れ」しかしない(判断なし)
List<TaskItem> all = repository.findAll();

// Service: 「未完了だけ」という判断(業務ルール)を持つ
int remaining = service.remainingCount();
  • TaskRepositoryfindAll()で全件をそのまま返すだけで、完了かどうかを気にしない
  • TaskServiceTaskRepositoryを使いながら、「未完了は何件か」「重複タイトルは禁止」のような判断を追加する
  • 画面側(ViewModel)はServiceだけを呼べばよく、Repositoryの存在すら知らなくてよい

業務ルールとEntityの検証の違い

TaskTitleはコンストラクタで「空文字は禁止」「50文字を超えたら禁止」を検証します。これは1つのタイトル単体で完結する検証なので、Entity(値オブジェクト)の責任です。一方「既存のタスクと同じタイトルは登録できない」というルールは、他のタスクと見比べる必要があります。1つのデータだけでは判断できず、複数のデータを横断する判断だからこそ、Repositoryを持つServiceの仕事になります。

まとめ

  • Repositoryは「そのまま出し入れ」、Serviceは「業務ルール・判断」を担当する
  • 1つのデータで完結する検証はEntity、複数のデータを見比べる判断はServiceが持つ
  • ViewModelはServiceだけを呼び、Repositoryの細部を知らなくてよい

次回: TaskServiceにルールを足しながら、TDDで実装していきます。