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?

Spring Bootで理解するMVCモデル入門|Controller・Model・Viewの役割を初心者向けに解説

0
Posted at

Spring Bootを学習していると、よく登場するのが**MVC(Model-View-Controller)**という言葉です。

Model
View
Controller

の頭文字を取ってMVCと呼ばれています。

しかし、Spring Bootにはさらに、

Controller
Service
Repository
Entity

などのクラスが登場するため、

「MVCって3つじゃなかったの?」
「ServiceやRepositoryはどこに入るの?」
「ModelってEntityのこと?」

と混乱しやすいです。

この記事では、MVCの基本からSpring BootでどのようにMVCが使われているのかまで整理します。


MVCとは?

MVCとは、アプリケーションの役割を大きく次の3つに分ける設計の考え方です。

要素 役割
Model データやビジネスロジックを扱う
View 画面を表示する
Controller リクエストを受け取り、ModelとViewをつなぐ

ざっくり表現すると、

Model      → データ・処理担当
View       → 画面担当
Controller → 交通整理担当

というイメージです。


Controllerとは?

Controllerは、ユーザーから送られてきたHTTPリクエストを受け取る役割を持っています。

Spring Bootでは、例えば次のように書けます。

@Controller
public class UserController {

    @GetMapping("/users")
    public String users(Model model) {
        model.addAttribute("name", "田中");
        return "users";
    }
}

ブラウザから、

GET /users

というリクエストが送られると、

@GetMapping("/users")

に対応するメソッドが呼び出されます。

Controllerはリクエストを受け取り、必要な処理を行ったあと、どのViewを表示するのかを決定します。

今回の場合、

return "users";

としているため、usersというViewを表示します。


Viewとは?

Viewは、ユーザーに表示する画面を担当します。

Spring Bootでは、Thymeleafなどのテンプレートエンジンを利用できます。

例えば、

src/main/resources/templates/users.html

に次のHTMLがあるとします。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>ユーザー</title>
</head>
<body>

    <p th:text="${name}"></p>

</body>
</html>

Controllerでは、

model.addAttribute("name", "田中");

としていました。

そのため、

<p th:text="${name}"></p>

の${name}に田中が入り、ブラウザには、

田中

と表示されます。

つまりViewは、

Controllerから渡されたデータを使って画面を表示する

という役割を持っています。


Modelとは?

ここが少しややこしいポイントです。

MVCにおけるModelは、単純に「Modelという名前のクラス」を意味するわけではありません。

Modelは、

アプリケーションのデータやビジネスロジックを担当する部分

という広い概念です。

Spring Bootでは、例えば次のようなクラスがModel側の処理を担当します。

Service
Repository
Entity

例えば、

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public List<User> findAll() {
        return userRepository.findAll();
    }
}

Serviceではアプリケーションの処理を担当し、

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

Repositoryではデータベースへのアクセスを担当します。

さらに、

@Entity
public class User {

    @Id
    @GeneratedValue
    private Long id;

    private String name;
}

Entityによってデータを表現します。

これらをまとめて、MVCでは広い意味でModel側として考えることができます。


SpringのModelとMVCのModelは少し意味が違う

Spring Boot初心者が特に混乱しやすいのがここです。

Controllerには、

public String users(Model model)

というコードが登場します。

このModelを見て、

「これがMVCのModelか!」

と思ってしまいがちですが、少し違います。

Spring MVCのModelは、

ControllerからViewへデータを渡すための入れ物

として使われます。

例えば、

model.addAttribute("name", "田中");

とすると、

<p th:text="${name}"></p>

のようにViewからデータを利用できます。

つまり、

MVCのModel

と、

org.springframework.ui.Model

は同じ言葉でも意味が少し違います。

ここは区別して覚えておくと混乱しにくくなります。


Spring BootでのMVCの流れ

例えば、ユーザー一覧画面を表示するとします。

処理の流れを単純化すると、

ブラウザ
   |
   | GET /users
   v
Controller
   |
   | findAll()
   v
Service
   |
   | findAll()
   v
Repository
   |
   v
Database

データを取得したら、今度は逆方向に戻ってきます。

Database
   |
   v
Repository
   |
   v
Service
   |
   v
Controller
   |
   | Modelにデータを格納
   v
View(Thymeleaf)
   |
   v
ブラウザ

コードにすると、例えば次のようになります。

@Controller
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/users")
    public String users(Model model) {

        List<User> users = userService.findAll();

        model.addAttribute("users", users);

        return "users";
    }
}

Controllerが直接データベースを操作するのではなく、

Controller
↓
Service
↓
Repository
↓
Database

というように役割を分けています。


なぜMVCに分けるのか?

「全部Controllerに書けば簡単なのでは?」

と思うかもしれません。

小さなアプリケーションなら、それでも動きます。

しかし、Controllerに、

HTTPリクエスト処理
データベースアクセス
業務ロジック
画面表示
入力チェック

などをすべて書いてしまうと、Controllerがどんどん巨大になります。

例えば、

@GetMapping("/users")
public String users(Model model) {

    // DBから取得

    // データを加工

    // 条件判定

    // 計算

    // Viewへ渡す

    return "users";
}

という状態になり、機能が増えるほど管理が難しくなります。

そこで役割を分けます。

Controller
    ↓
HTTPリクエストの処理

Service
    ↓
ビジネスロジック

Repository
    ↓
データベースアクセス

View
    ↓
画面表示

これを責務の分離と呼びます。


MVCにするメリット

MVCによって役割を分離すると、次のようなメリットがあります。

コードの役割が分かりやすい

例えばDB関連の処理を確認したい場合はRepository、業務ロジックを確認したい場合はServiceを見る、といったようにコードを探しやすくなります。

修正しやすい

役割が分かれているため、変更の影響範囲を小さくしやすくなります。

テストしやすい

ServiceやControllerなどを分離していることで、それぞれを個別にテストしやすくなります。

大規模なアプリケーションにも対応しやすい

機能が増えても役割ごとにコードを整理できるため、コードが巨大化するのを防ぎやすくなります。


Spring BootではMVCをさらに細かく分けている

MVCは、

Model
View
Controller

という大きな役割分担です。

Spring Bootのアプリケーションでは、さらに役割を細分化して、

Controller
↓
Service
↓
Repository
↓
Database

という構成をよく使用します。

そのため、

MVC = Controller・Service・Repository

という意味ではありません。

MVCという大きな設計の考え方があり、その中でSpring Bootではさらに責務を細かく分けている、と考えると理解しやすいです。


まとめ

MVCとは、

Model
View
Controller

の3つにアプリケーションの役割を分ける設計の考え方です。

それぞれの役割は、

要素 主な役割
Model データ・ビジネスロジック
View 画面表示
Controller HTTPリクエストを受け取り処理を振り分ける

となります。

Spring Bootではさらに、

Controller
↓
Service
↓
Repository
↓
Database

のように役割を細かく分けることが一般的です。

また、

org.springframework.ui.Model

はMVCそのもののModelを表しているわけではなく、ControllerからViewへデータを渡すために使われるオブジェクトです。

最初は、

Controller = 受付・交通整理
Service    = 処理
Repository = DBアクセス
View       = 画面

くらいのイメージから理解していくと、Spring Bootのコード全体の流れが見えやすくなります。

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?