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?

Controller:Service:DB参照のリファクタリングについて 勉強記録

Posted at

今回学んだこと

・orElseThrowによるエラーページのリファクタリング
・Contorollerクラスからのデータの所得
・その他のリファクタリング

リファクタリング前後のコードの変化

リファクタリング前
TaskContoroller.java
    @GetMapping("/{id}/editForm")
    public String showEditForm(@PathVariable("id") long id, Model model) {
        var taskEntity = taskService.findById(id)
                        .orElseThrow(() -> new IllegalArgumentException("Task not found"));
        var form = new TaskForm(taskEntity.summary(), taskEntity.description(), taskEntity.status().name());
        model.addAttribute("taskForm", form);
        return "tasks/form";
    }
リファクタリング後
TaskContoroller.java
@GetMapping("/{id}/editForm")
    public String showEditForm(@PathVariable("id") long id, Model model) {
        var form = taskService.findById(id)
                .map(TaskForm::fromEntity)
                .orElseThrow(TaskNotFoundException::new);
        model.addAttribute("taskForm", form);
        return "tasks/form";
    }

解説

前提としてContorolerクラスは見やすくわかりやすく書く,意識として↓

理由 内容
💡 役割が限られているから 接続役としてだけに専念するべき
🧹 責任を分けたいから サービスやリポジトリと分業
🔧 メンテしやすいから 見通しが良くなり、バグも見つけやすい
🔁 変更に強いから 他の層に影響を与えずに変更できる
リファクタリング前(主な動作)

まず@GetMapping("/{id}/editForm")でurlが指定された時にGetするメソッドとして定義する。

まず@GetMapping("/{id}/editForm")でurlが指定された時にGetするメソッドとして定義する。

editFormを作るためのメソッドなのでString型のshowEditFormとして@PathVariableを使ってurlのidを変数として受け取り、さらにmodelでビューに返す(Tymeleafを使用しているのでJsonで返すときは別)

リファクタリング前でtaskEntityを定義してサービスクラスのfindByIdを呼び出しDBからidを所得している

.orElseThrow(() -> new IllegalArgumentException("Task not found")でOptional型が返された時にidが違った場合、Task not foundを返す文である。

model.addAtributeで"taskForm"がビュー側で呼び出された場合formというDBにアクセスしたいのでtaskEntityからデータを取り出し画面表示用のTaskFormをnewしている

リファクタリング後

主な変化として定義する変数をformひとつにし、.mapを使うことで可読性が高い文章になっている

.map(TaskForm::fromEntity)の役割としてTaskEntity → TaskForm に変換する 静的メソッド(static method) である。リファクタリング前のTaskFormに書いてあった引数をTaskFormの性的メソッドの中にTaskForm fromEntityと定義することで簡潔に書いている。

.orElseThrowの中はTaskNotFoundExseptionという例外クラスを作ることで簡潔に書いている

外伝:例外クラス

TaskNOtFoundException.java
@ResponseStatus(HttpStatus.NOT_FOUND)
public class TaskNotFoundException extends RuntimeException{
}
重要なパターン

@ResponseStatus(HttpStatus.NOT_FOUND)  → この例外が発生したときに HTTPステータスコード「404」 を返すように指示してる

・extends RuntimeException
 → チェックされない例外(Unchecked Exception) として扱うことで、throws 書かなくてOK

まとめ

それぞれの役割ごとにクラスを分けて書くことでエラーに対処しやすくなり可読性が高いプログラムになることが理解できた。tymeleafを使うか使わないかで大きな差が出るが3層アーキテクチャの考え方は重要であることがわかった。なるべく変数は少なくコードは短く!!
(文字多くてごめんね)

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?