実装の7割はコーディングの前に終わっている

# 初めに

開発経験初期のころ、あまりどのように実装タスクを進めていけばいいのかわからず、手戻りやスケジュール遅延を幾つかしてしまっていました。それからある程度どのように開発を進めていけばそのようなことが起こらないか自分の経験則である程度固まってきたのでそれを書いていけたらと思います。

## 失敗談

まだ開発経験が少なかった昔の自分は何か機能実装のタスクがアサインされた際、それをアサインされてからすぐコーディングをしながら色々考えていました。そしたら下記のような問題によくぶち当たっていました。

- 次何を書こう
- あれ、ここの仕様どうだったっけ？
- やばい、この仕様ならdbの方から修正しないといけない

そのせいで予定していたスケジュールを大幅に遅れてしまったり、レビューの際に手戻りが発生してしまったりなど、全く効率よく実装を行うことができていませんでした。

## 実装手順書を書くようになった

今までの失敗を踏まえ新たな実装タスクがアサインされた際、そのプロジェクトのPMに対して今までの悩みを相談したら、実装手順書を記述してそれをPMと話し合い、手順書が確定してからコーディングを行うようにという指示を受けました。なので下記の点を実装手順書へ書くようにしました。

1. **概要**
   - 今自分がやろうとしていることは何なのかを整理する
2. **現時点での自分の理解、仕様についての意見**
   - 特に仕様についての理解が怪しい、不明な点について現時点での自分の理解
   - このような仕様にした方がdbとの連携であったり、拡張性をもたすことができるのでいいのではないのだろうかなどの意見
3. **現時点での実装手順**
   - 実際にこの機能を実装する際、このような手順でやったら実装がうまく行くという手順をPR単位で考える（上記のPR単位は小さければ小さいほどいいと考えている）

ここまで記述した段階でPMに投げてアドバイスをもらう・仕様を考える時間をとってさらに実装手順書、今回の機能での仕様を詰めていきました。

## 実際どうだったか

とても良かったです。まず仕様の部分で自分が思っている仕様とPMが思っている仕様の理解のすり合わせを事前にできることにより、仕様に対してのズレが０になりました。それにより仕様に対しての手戻りがほとんどなくなりました。
また実装手順を詳細にコーディングの前に記述することにより、どの部分を最初に実装すべきか、どのような順序で進めていくべきかが事前に明確になり、効率的に作業を進めることができるようになりました。これにより、迷いなくコーディング作業を進めることができるようになりました。
今まで５回程度実装手順を大きめの機能を実装する時は書いているのですが、書く前と後では効率が段違いです。

## 自分の実装手順書の例

実際にどのような手順書を書いていたのか、簡単にですが下記に記述していきたいと思います。今回は一例で見積の承認フローに対してどのように実装するのかをまとめたものになります。

### 概要

本機能は、見積りの作成や詳細確認時に、社員の権限を超える見積もりを作成しようとする場合に承認フローを要求する。これには適切なバリデーションが必要である。

#### 現在の承認ステータス管理

`isApproval`フィールドにより、以下のステータスを管理する。

- `false`：承認が必要
- `true`：承認済み
- `null`：承認不要

#### 新規作成時と更新時の条件

##### 新規作成時

- **社員権限を超える見積もり**：`false`を設定する
- **社員権限内の見積もり**：`null`を設定する

##### 更新時

- **承認者による更新**：`false`から`true`に変更可能。明細を追加して権限を超えた場合は、セレクトを`disable`にして`false`を設定する

#### 受注と見積もりの関係

受注はすべて見積もりに紐づく。受注作成時には、既に承認された、または承認が不要な見積もりから選択されるべきである。しかし、受注作成後に見積もりが編集され、承認が必要な状態に変更された場合、どのように受注を管理すべきかが課題となる。
#### 課題点と提案

1. **承認ステータスの管理方法**：
    - 現在の`null`、`false`、`true`の三状態ではなく、明確な状態管理・拡張性のために`enum`で管理すべきかどうかを検討する

2. **受注作成後の見積もり変更対応**：
    - 受注作成後に見積もりが未承認に変わった場合、受注の`validityCategory`を`false`に設定する等、適切な対応策を検討する

#### 以上を持ってPMと話す点

##### 承認ステータスの見直し

現在、承認ステータスには「承認が必要」「承認済み」「承認不要」の3種類があるが、「承認不要」の状態を設ける必要があるのかどうか。理由としては、実質的には作成者自身の権限内で処理されるため、自己承認のような形になると考えることができる。そのため、ステータスは「承認が必要」「承認済み」の2種類に絞る方が分かりやすいのではないかと思う。

##### 承認後の見積もりの変更対応

1. **見積もり変更後の受注の扱い**：一度承認された見積もりに基づいて受注が作成された後、その見積もりが編集され承認が必要になった場合の対応策を検討する。見積もりの承認状態は受注作成や更新の際にチェックされ、必要に応じて受注の状態を更新する必要がある

2. **承認済み見積もりの再編集**：一度承認された見積もりが再び編集され、承認が必要になった場合の対応策として、その見積もりの編集を禁止し、必要に応じて新たな見積もりを作成してもらうのはどうか

##### フロントエンドとバックエンドでの権限制御

- **フロントエンド**：ユーザーが新たな行を追加した際に、現在のユーザーの権限を超えているかどうかをリアルタイムでチェックし、超えている場合はエラートーストを表示して操作を制限する

- **バックエンド**：APIリクエストを受けた際に、リクエスト送信者の権限を確認し、処理が許可された範囲内であるかを検証する。権限を超える操作を試みた場合は、適切なエラーレスポンスを返す

### 実装手順

1. スキーマの作成
2. バックエンドでのバリデーション
3. フロントエンドでのバリデーション
4. 承認メール機能の実装
5. QA
<br>
実際にはもっと細かく実装手順について記述していますが、ここでは要点のみを記載しています。<br>ここまで記述したらあとはPMに壁打ちをしてアドバイスなどをもらい修正して、それの合意を経て実装という流れになります。話し合いで決まったことなども手順書に書き足していくと後々見返したときに話した内容を思い出せて良いと思います。

あとは手順通りに実装するだけなのでコーディングだけに集中することができます。
今まで考えながらのコーディングをしていたのでとても時間がかかっていたのですが、最初の思考の部分に時間を割くことでコーディングの部分を体感全実装時間の3割程度の時間で済ますことができています。

## まとめ
結構これは個人開発でも汎用できるのでまだチーム開発の経験がない人や、プログラミング初心者の人にもぜひ書いてほしいです。経験が浅い人にこそ手順書はしっかり書いてもらいたいです。

手順書を書くようになって、エンジニアの本当の価値はコーディングをすることではないのかもしれないと思っています。どのような手順で実装すればうまくいくかを考え切れることに対して価値があるのかもしれません。

最初は考えていることを自然言語に書き出すことを面倒に感じたり、面白くないと思うけど、実際にこのフェーズを越えさえすれば、あとはコーディング作業するだけだからすぐに実装終わるよ。やったことない人は騙されたと思ってやってみて！