【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-②設計-

todoアプリケーションの設計をしていきます。

# はじめに

設計とは、アプリケーションの要件に基づいて、アプリケーション全体の構造や動作を計画するプロセスです。良い設計は、アプリケーションの拡張性、保守性を高め、開発プロセス全体の効率性を向上させることを期待されます。

難しく書きましたが、要するに、要件をもとにシステムに実装する機能を明確化、具体化していくプロセスです。エンジニアはこの設計（How）の部分で価値を発揮することを期待されます。

設計では、主に「画面・機能・データ」 を検討します。この単位だとまだ大雑把なので、もう少し検討しやすい形に整えます。設計する単位まで落とし込むと、今回は以下の４つを検討しTODOアプリケーションを設計していきます。実際の案件では、もっとたくさんの仕様書を作成することもあるかもしれませんが、今回では最低限必要なものだけピックアップしてしました。

TODOアプリケーションの作成プロセスを、「仕様を考える」と「仕様をコーディングする」とわけたときに、「仕様を考える」に該当する最低限必要なものを設計として扱うことにします。例えば、コードを書くときに考えなくてもよいように、バリデーションチェック時のエラーメッセージなど画面設計の中に加えています。

1. 機能一覧:
アプリケーションが提供する主要な機能を一覧化します。開発の範囲と目標が明確になり、プロジェクト全体の方向性を示します。
2. 画面設計:
ユーザーが操作する画面を定義します。画面設計には、ユーザーインターフェース（UI）の要素、画面一覧、画面遷移、出力メッセージ文言が含まれます。
3. URL設計:
アプリケーション内の異なるページや機能にアクセスするためのURLを設計します。
4. テーブル設計:
アプリケーションが扱うデータの構造を定義します。

:::note info
設計のポイント

設計はドキュメントを作ることが目的ではないので、思うに、設計のポイントは手段と目的を間違えないことです。

ドキュメントを作ることを目的にして設計を行うと、ぱっと見ると設計ができているようにみえます。しかし、字面が設計書の艇をなしているかに注力してしまうので、想像力が限定的になり、考慮が足りないドキュメントができあがってしまいます。設計は、課題を解決したり業務を効率させるための1つのプロセスです。実際にシステムが動くところを想定して設計を進めていきたいです。
:::


# 機能一覧
では、機能一覧を作成していきます。イントロダクションで記載した内容をもとに、TODOアプリケーションとして、必要な機能を書き出していきます。

| 番号 | 機能                | 説明                                                                                               | 登録/表示/変更/削除可能な項目                              |
| ---- | ------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------ |
| 1    | タスクの登録        | ユーザーが新しいタスクを入力し、ToDoリストに追加できる機能。                                      | タイトル、説明、期日                                    |
| 2    | タスクの一覧表示    | ユーザーがToDoリスト内の全てのタスクを閲覧できる機能。タスクのタイトル、説明、期日、ステータスを表示。 | タイトル、説明、期日、ステータス（未着手、作業中、完了） |
| 3    | タスクの変更        | ユーザーが既存タスクを変更できる機能。                                                            | タイトル、説明、期日、ステータス                         |
| 4    | タスクの削除        | ユーザーが既存タスクを削除できる機能。物理削除。                                                  | -                                                      |

ユーザーがタスク登録するなど管理するところを想像しながら書いていきます。CRUD（Create＝作成機能、Read＝閲覧機能、Update＝変更機能、Delete＝削除機能）を念頭に置いて検討すると、漏れがなくなります。今回は画面での操作を想定してCRUD通りに検討したら完了ですが、実際のプロジェクトではさらに、API、帳票、メール、バッチの機能も検討する必要があります。

# 画面設計
続いて画面設計をしていきます。画面設計では、「1.画面遷移」「2.画面一覧」「3.画面項目」「4.バリデーションメッセージ」をそれぞれ検討していきます。

## 1.画面遷移
画面の遷移を検討していきます。一覧画面を起点にして変更画面などに遷移するパターンと、一覧画面から詳細画面に遷移して詳細画面から変更画面に遷移するパターンをよく見かけますね。今回は、前者の「一覧画面を起点にして変更画面などに遷移するパターン」で画面遷移を検討しました。詳細画面で内容を確認することが必要なほど登録項目が多くないので、詳細画面はつくらなくてもよいかなという判断です。

以下のような遷移になりました。確認画面と完了画面を入れるオーソドックスな画面遷移にすることにしました。一覧画面から、登録画面、変更画面、削除確認画面に遷移するので、一覧画面にはそれぞれの画面に遷移するようなボタンが必要そうですね。また、戻ることができた方がよいので、1つ前の画面に戻れる箇所は画面遷移を⇔で表現しました。そして、エラーになった場合に備えて、エラー画面も記載しました。

一覧画面　⇔　登録画面　⇔　確認画面　→　完了画面　（→　一覧画面）
　　　　　⇔　変更画面　⇔　確認画面　→　完了画面　（→　一覧画面）
　　　　　→削除確認画面　→　完了画面（→　一覧画面）
（エラー発生）　→エラー画面

## 2.画面一覧

画面遷移をもとに画面一覧を作成しました。確認画面と完了画面は登録画面後と変更画面後で2か所登場しますが、1つにまとめました。全部で7枚画面があるようです。

- 一覧画面
- 登録画面
- 変更画面
- 確認画面
- 完了画面
- 削除確認画面
- エラー画面


## 3.画面項目
次に画面項目を検討しました。機能一覧に記載した内容も踏まえつつ、画面に表示する項目を整理しました。

- 一覧画面
新規登録　ボタン　新規登録画面に遷移する
タイトル　出力　繰り返しあり
説明　出力　繰り返しあり
期限　出力　繰り返しあり yyyy/mm/dd
変更　ボタン　変更画面に遷移・繰り返しあり

- 登録画面
タイトル　入力　100文字まで/必須
説明　入力　200文字まで
期限　入力　必須　yyyy/mm/dd
確認　ボタン　確認画面に遷移
もどる　ボタン　一覧画面に遷移

- 変更画面
タイトル　入力/出力　100文字まで/必須
説明　入力/出力　200文字まで
期限　入力/出力　必須　yyyy/mm/dd
ステータス　入力/出力　必須 0~3までの範囲
確認　ボタン　確認画面に遷移
もどる　ボタン　一覧画面に遷移

- 確認画面
タイトル　出力
説明　出力
期限　出力　yyyy/mm/dd
ステータス　出力　変更のときのみ
完了　ボタン　登録/変更処理を実行し、完了画面に遷移
もどる　ボタン　確認画面に遷移

- 削除確認画面
タイトル　出力
説明　出力
期限　出力　yyyy/mm/dd
ステータス　出力　
完了　ボタン　削除処理を実行し、完了画面に遷移
もどる　ボタン　確認画面に遷移

- 完了画面
完了メッセージ　出力　
"The data was successfully saved."登録したときのみ表示
"The data was successfully updated."変更したときのみ表示
"The data was successfully deleted."削除したときのみ表示
go to list ボタン　一覧画面に遷移

- エラー画面
エラーメッセージ　出力
エラーが発生しました。

ヘッダー（共通）
- アプリタイトル　出力

## 4.バリデーションメッセージ
続いてバリデーションチェックエラーメッセージを検討しました。まず、どんなバリデーションエラーが必要か考えて、エラーメッセージを検討しました。

- 必須チェックエラー：
- 文字数チェックエラー：

- Titleを入力してください。
- 100文字以内で入力してください。
- descriptionは200文字以内で入力してください。
- deadlineを入力してください。

# URL設計
URL設計では、どんなURLのどのHTTPメソッドでどんな処理がはしるのかまとめていきます。特に、「どんなURLのどのHTTPメソッドで」を詳しく検討していきましょう。処理は上記までの設計でどんな処理が必要なのかある程度見当がつくので、「どんなURLのどのHTTPメソッドで」を検討したあとに整理できると思います。

URLを検討する際のポイントは「階層構造化」と「適切なキーワードの使用」です。

URLを構造化することは、SEOにおいてもユーザーの利用しやすさにおいても重要です。webサイトは、記載内容やジャンルによってセクションを分けて分けており、大きなカテゴリーから小さなカテゴリーのページに遷移できるようになっていることが多いです。例えば、コーポレートサイトで、サービスというセクションの中にコンサルティング事業ページとSI事業ページがあったとしたら、URLは以下のようになります。

コンサルティング事業ページ→/service/consulting
SI事業ページ→/service/systemintegration

このように「/」を使うことによってセクションを分けたり、カテゴリーの大小を分けて、階層構造化することができます。結果、URLをみると、ユーザーが瞬時にアプリケーション内の位置を把握することができます。

次に、どんなキーワードをURLに含めるとよいか見ていきましょう。ポイントは「何を（名詞）」「どうするの（動詞）」わかるようにキーワードを設定することです。例えば、タスクを（何を）、変更する（どうする）ページであれば、task（何を）とedit（どうする）というキーワードを使うとよさそうです。このように、「何を（名詞）」「どうする（名詞）」をもとにURLで使う言葉を選んでいくと、重複なくシンプルで読み取りやすいURLをつくることができます。

＊

次に、「どのHTTPメソッドで」を検討します。HTTPメソッドとは、HTTPを使用してクライアントとサーバー間で通信する際に使用される操作の種類を指します。

HTTPメソッドは、クライアントがサーバーに行いたいアクションを伝えるために使用されます。画面からの操作の場合は「GETメソッド」または、「POSTメソッド」を使用します。HTTPメソッドは他にも存在しますが、他のHTTPメソッド（例：PUT、DELETEなど）は、HTMLのフォームで直接指定することができません。

この「GETメソッド」または、「POSTメソッド」はそれぞれ役割があり、セキュリティなどの観点で使い分けることが推奨されています。それぞれの役割を説明すると、「GETメソッド」はデータの参照や取得に適しています。「POSTメソッド」はデータの送信や登録に適しています。つまり、データの参照するときは「GETメソッド」、データを登録するときは「POSTメソッド」を選択するとよいでしょうか。

以上のポイントを踏まえて、TODOアプリケーションのURL設計を以下のように整理しました。確認画面から完了画面に遷移するときはリダイレクトをさせることも考慮に入れて設計しています。

URL: /task/list
HTTPメソッド: GET
処理： タスク一覧表示

画面名: タスク新規登録画面
URL: /task/add
HTTPメソッド: GET

画面名: タスク変更画面
URL: /task/edit
HTTPメソッド: GET

画面名: タスク確認画面
URL: /task/confirm
HTTPメソッド: GET

画面名: (リダイレクト先が存在しないため、リダイレクトされないため画面名はなし)
URL: /task/save
HTTPメソッド: POST

画面名: タスク完了画面
URL: /task/complete
HTTPメソッド: GET

画面名: タスク削除確認画面
URL: /task/delete
HTTPメソッド: GET

画面名: (リダイレクト先が存在しないため、リダイレクトされないため画面名は不明)
URL: /task/delete
HTTPメソッド: POST

画面名: タスク確認画面からタスク変更画面
URL: /task/back
HTTPメソッド: GET

画面名：エラー画面
URL: /error
HTTPメソッド: GET

:::note info
【FYI】
Google における URL 構造のベスト プラクティス
https://developers.google.com/search/docs/crawling-indexing/url-structure?hl=ja
:::


# DB設計
最後に、DB設計を行います。DB設計のセオリーとしてよく3層スキーマや論理設計物理設計という話が出てきます。今回のTODOアプリケーションは大掛かりなものではないので、セオリー通りには進めず少し省略して検討していきます。このTODOアプリケーションのDB設計は少なくともテーブル定義ができていればOKなので。

今回は画面で入力した値をDBに登録するので、画面設計で検討した値がDBの項目になりそうです。加えて、画面に出てこない値や拡張性を考えて持たせておく項目などもあるので、順番に検討していきます。

まず、どんなテーブルが必要か検討します。テーブルを検討するときは、要件から意味のある名詞を抽出します。
ここでいう意味のある名詞とは、「1.具体的な実体を指す単語」または、「2.概念や概念的な実体を指す単語」を指します。「1.具体的な実体を指す単語」とは、例えば、"タスク"や"ユーザー"などのことで、DBで格納される可能性があります。「2.概念や概念的な実体を指す単語」とは、システム内で重要なデータや概念を表現するために使用されることがあります。例えば、"注文"や"取引"などのことで、DBで格納される可能性があります。

今回のTODOアプリケーションでは、「タスク」がこの意味のある名詞に該当します。よって、テーブルとしては、タスクテーブルがあるとよいでしょう。今回は実装しませんが、「ユーザー」も意味のある名詞に該当します。認証機能を実装するのであれば、ユーザーテーブルをつくるのがよいでしょう。

＊

次に、カラムを検討します。タスクテーブルのカラムを検討します。要件から必要なカラムを抽出していきましょう。まず、画面設計で検討した入力項目が必要です。具体的には、タイトル、説明、締切、ステータスです。

そして、今回はリレーショナルデータベースを使用します。リレーショナルデータベースは関係性のある複数の二次元表として情報を扱います。このリレーショナルデータベース内のデータの正確性と整合性を確保するためにデータを一意にする必要があります。そこで、タスクIDという他と重複しない値を設定しておくことが一般的です。このタスクIDは主キー（primary key）──この値を指定することである1行を完全に指定できる列のことと呼びます。

さらに、登録日、変更日もカラムとして用意しましょう。登録日はタスクが作成された日時を示し、変更日は最後にタスクが更新された日時を示します。これによって、データの追加または更新を追跡することができます。
特に、データの変更履歴を追いたい場合に有効です。そして、今回のTODOアプリケーションで使用しませんが、このシステムの拡張性（機能追加）を考えて、ユーザーIDと、削除フラグもカラムに追加しましょう。ユーザーIDは認証機能がこのTODOアプリケーションに追加されたときに、登録されたタスクは誰が作成したのかを表すときに使用します。

一方、削除フラグは、このTODOアプリケーションの削除機能は物理削除ではなく、論理削除になったときに必要になります。DBのカラムを後から帰るのは大変なので、拡張性を考えて、カラムを予め入れておきます。

＊

次に、テーブルのリレーションを検討します。TODOアプリケーションでは、タスクテーブルが主に使用されますが、将来的にユーザーテーブルを追加する場合、ユーザーとタスクの間に1対多のリレーションが発生します。つまり、1人のユーザーは複数のタスクを持つことができます。これを考慮して、タスクテーブルにユーザーIDを持たせ、ユーザーテーブルの主キーとリレーションを形成します。

最後に、型や桁数なども検討していきます。タスクテーブルの各カラムについて、それぞれ適切なデータ型と桁数を設定します。例えば、タスクIDは整数型（int）、タイトルは文字列型（String）で最大100文字、説明は文字列型で最大200文字、締切と登録日、変更日は日時型（LocalDateTime）などです。


ここまでを整理すると、以下のようになります。

	タスクID taskId;
    タイトル　title;
    説明 description;
    締切 deadline;
    ステータス　status;
    ユーザーID　userId;
    登録日　created_at;
    変更日 updated_at;
    削除フラグ deleteFlg;


:::note info
【FYI】
【入門】データベース設計まとめ
https://qiita.com/KNR109/items/5d4a1954f3e8fd8eaae7
:::

次の投稿では、実装方針を確認し、環境構築を行っていきます。

[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-①イントロダクション-](https://qiita.com/aki_number16/items/4ce2c61297e6754928ce "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-①イントロダクション-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-②設計-](https://qiita.com/aki_number16/items/9507e7f9477725e722cd "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-②設計-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-③実装方針と環境構築-](https://qiita.com/aki_number16/items/79a514c5b8a70fbc41ac "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-③実装方針と環境構築-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-④一覧機能の作成-](https://qiita.com/aki_number16/items/7cc7d4b522fd9a3d6dc8 "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-④一覧機能の作成-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑤新規登録機能の作成-](https://qiita.com/aki_number16/items/bd4a559db587a502100e "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑤新規登録機能の作成-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑥変更機能の作成-](https://qiita.com/aki_number16/items/554ed617fa1b314e794c "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑥変更機能の作成-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑦削除機能の実装-](https://qiita.com/aki_number16/items/648cff45366445135000 "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑦削除機能の実装-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑧戻る機能の実装-](https://qiita.com/aki_number16/items/548f1918830024df7de8 "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑧戻る機能の実装-")
[【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑨例外処理の実装-](https://qiita.com/aki_number16/items/7ccad8e9805d58942eba "【Java】Spring Bootを使ったToDoアプリケーションを作成しよう-⑨例外処理の実装-")