開発タスクの作業手順

# はじめに
私がWeb系企業でエンジニアとして働いて1年半ほど経過しました。
そんな中で一番困ったのが、開発タスクをどのような作業手順で行えばいいかということでした。
意外とこのことについて書いてある記事がなかっため、自身の経験や参考書、先輩エンジニアの助言などをもとに1年半かけてたどり着いた作業手順について書いてみました。
開発タスクをどのような手順で行うべきか分からず困っている人の参考になれば幸いです。

# 作業手順
作業手順は以下のとおりです。
```md
- [] 企画内容の理解
- [] ToDoリスト作成
- [] 最小要求(+理由)の理解/議論(追加・変更・削除)/決定: 要共有
- [] 既存仕様の理解
- [] 技術調査
- [] 変更仕様の提案/議論/決定: 要共有
- [] 設計
- [] 変更範囲
- [] 影響範囲
- [] 工数見積り: 要共有, 以降遅延検知したら即共有
- [] テストケース(自動テスト・E2Eテスト)洗い出し
- [] 実装
- [] テスト(自動テスト・E2Eテスト)
- [] リファクタリング
- [] PR作成/レビュー依頼
- [] レビュー指摘対応
- [] リリース前準備依頼(to CS)
- [] リリース
- [] リリース完了連絡
- [] 不具合対応
```
以降では用語の説明と、各作業についての詳細な説明をしていきます。

# 用語
- 要求: 企画者が実現したいことを示します。
- 変更仕様: 要求をシステムで実現した場合の、システムの振る舞いを示します。要求はあくまで人間目線で実現したいこと、仕様はシステム目線での要求の実現方法を意味します。

# 企画内容の理解
まずは企画書など、開発依頼をされる際に渡される資料をざっと理解します。
ここで書かれている企画内容は、必ずしも適切にまとめられたものではないです(詳細は後述)。
なので、ざっと理解したら次の作業に移りましょう。

# ToDoリスト作成
基本的に[作業手順](https://qiita.com/ken1min86/items/4cdf59920f273aa0f202#%E4%BD%9C%E6%A5%AD%E6%89%8B%E9%A0%86)に記載したことをToDoリストとして利用し、上から順にやっていけばいいのですが、タスクの種類によっては追加で行うべき作業が発生するため、その作業をToDoリストに追加します。
ある程度開発に慣れていると、業務ドメインやコードについての理解が進んでいるため、この段階でToDoリストを作成しきれますが、そうでない場合は適宜更新していけばよいです。

ポイントは、ToDoリストでやることを適切な粒度(自分が1つの作業をしていると感じられるくらい細分化されたような粒度)で管理しているところです。
システム開発は非常に複雑な作業であるため、やることを適切な粒度に分けて1つずつ作業を行わないと、何をするべきかを見失ったり、煩雑すぎて集中して作業ができなかったりするためです(集中するにはある程度作業が単純である必要があると思っています)。
また、後でやろうと頭の中で記憶をしようとすると、そのことで脳内メモリを使ってしまうため、目前の作業に集中しきれなくなり非効率になります。
やることが増えたら都度ToDoリストに追記して、無駄なメモリ消費を減らすのをおすすめします。

# 最小要求(+理由)の理解/議論/決定: 要共有
まず前提として、私は企画者に企画書を以下のようなフォーマットで記載してもらっています。

## フォーマット
■要求
|要求|理由(要求の背景)|
|-|-|
|hoge|foo|

■仕様案
(機能変更の場合)
|要求|既存仕様|変更仕様|
|-|-|-|
|hoge|foo|baa|

(機能追加の場合)
|要求|変更仕様|
|-|-|
|hoge|foo|

このようなフォーマットにしている理由について説明します。

まず要求と仕様を明確に分けているのは、こうしないと要求として変更仕様を書かれることが多いからです。
要求とは企画者が実現したいことであり、変更仕様とはそれをシステムの形で実現したときの振る舞いを指します。
これらの違いはエンジニアからすると比較的明確なのですが、非エンジニアである企画者からは区別がつきにくいと感じている方が多い気がします。
最低限、要求と変更仕様を分けるという心がけをしてもらうため、要求と仕様を明確に分けています。

また本来、変更仕様はシステムに明るいエンジニアが要求を元に提案するものです。
しかし、企画者が変更仕様を思いつく場合があるため、あくまでそれは仕様案の1つとして検討するという意味合いで、仕様案として記載をしてもらいます。

また、各要求に対して理由を記載してもらうことで、企画者の真の要求を理解できるようにしています。
上述したように、要求として変更仕様が書かれたり、記載された要求自体が誤っていることがあります。
しかし、その理由(要求の背景)が間違っていることはほぼありません。
そのため、理由を記載してもらうことで、記載された要求から逆算して、真の要求を推測することができます。

## 作業内容
前置きが長くなりましたが、この工程で行う作業を説明します。
まずは、記載された内容を元に、要求、理由、仕様案を整理します。
上述したように、要求として仕様が書かれていたら仕様の箇所に内容を移したり、要求が真の要求になっていなかったら、理由を元に要求を推測したりします。
そして、整理した内容が企画者の意図にあっているかや、解決しなかった疑問点などの確認など企画者と行い、要求を確定させます。

また、できるだけ要求は最小になるようにします。
まだ世にでていない機能はあくまで仮説であり、それが真に価値があるかどうかは実際にリリースしてユーザーに使用してもらわないとわかりません。
真の価値がわかっていない状態では、まずは最小要求でリリースするのが一番安全なため、このようにします。

# 既存仕様の理解
タスクに関連がある、現行の仕様を理解します。
すでにコードを読んだことがある箇所に変更を加えたり機能追加したりする場合は、関連する箇所がわかっているのでそこのコードを読んで、現行仕様を理解します。

そうでない場合は、関連箇所は明確にはわからないので、まずは関連しそうな箇所をざっと洗い出します。
その後、それらの箇所を読みながら関連箇所を探して、現行仕様を理解します。

コードリーディング時に特に私が気をつけているポイントは以下のとおりです。
- 関係のないコードは可能な限り読み飛ばすことで、必要十分量だけ読むようにする。
- 関連箇所を理解するときは、処理内容を自然言語でメモしながら理解する(プログラミング言語を読むだけだと理解した気になっている可能性があるため、自然言語(日本語)に変換することで理解できていることを確かめる)。
- 構造から理解をする。いきなり細かい処理まで理解しない。

詳細に理解したい場合は、私がコードリーディングについて調べたときに特に参考になったものを[こちら](https://qiita.com/ken1min86/items/4cdf59920f273aa0f202#%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0)に記載しているので、そちらを参照ください。

# 技術調査
既存仕様を理解するときに、よくわからない技術がでてきたときや、変更仕様を考えるときに必要な技術については、別途調べてメモをします。

# 変更仕様の提案/議論/決定: 要共有
ここまでこれば、変更仕様を考えるために必要な情報はすべて揃っています。
変更仕様を考えた上で、企画者と認識のズレがないか議論し、仕様を決定します。

ちなみに私の場合は、変更仕様を[こちら]( https://qiita.com/ken1min86/items/4cdf59920f273aa0f202#%E5%A4%89%E6%9B%B4%E7%AF%84%E5%9B%B2:~:text=foo-,%E2%96%A0%E4%BB%95%E6%A7%98%E6%A1%88,-(%E6%A9%9F%E8%83%BD%E5%A4%89%E6%9B%B4%E3%81%AE )のように記載することで、どの要求を満たすためにどういう仕様にするかや、既存の仕様がどう変わるかが理解しやすいようにしています。

# 設計
変更仕様を実現する際に、DB設計やクラス設計などを考える必要がある場合は、まずはそれらについて考えておきます。
設計に自信がないときは、この段階で上長などにレビューをしてもらいます。

# 変更範囲
変更仕様を実現するための、変更範囲(変更箇所)と具体的な変更方法を考えます。
私の場合は、変更仕様を整理した箇所に、以下のように付け加えることでこれらを整理しています。

|要求|既存仕様|変更仕様|変更範囲|変更方法|
|-|-|-|-|-|
|hoge|foo|baa|app/model/...|fizzする|

注意点として、まだこの段階ではコーディングはしません。
コーディングをするのは、どこをどうすればいいかをすべて考えた後に行います。
そうしないと、コーディングをする中で考慮漏れに気づき、すでに書いたコードについても再度考慮し直さなければならないなどような手戻りが発生しうるからです。

# 影響範囲
変更仕様を実現するための変更によって、影響を受ける箇所(影響範囲)と対処方法を考えます。
これは、実装しながら考えることもあります。
基本的には、git grepやfindなどで影響箇所を洗い出した後、各影響箇所に対して対処方法を考える感じです。
特に難しいことはないので詳細は割愛します。

# 工数見積り: 要共有
実装〜リリース完了までに所要する工数を見積もります。
ここまでくれば実装することはかなり具体的にわかっているので、見積もりし易いと思います。
細かい見積もり方法を記載すると長くなってしまうので割愛します。
需要がありそうであれば別途記事を書こうと思います。

見積もったら企画者にリリース目処を共有します。
以降、予定工数よりもズレが発生した or ズレが発生しそうになったら、その場ですぐに企画者に連絡し、リリース目処の再調整等します。

# 以降の作業
特に説明することはないので省略します。

# 参考
## 要求定義
- [要求を仕様化する技術・表現する技術](https://www.amazon.co.jp/%E3%80%90%E6%94%B9%E8%A8%82%E7%AC%AC%EF%BC%92%E7%89%88%E3%80%91%EF%BC%BB%E5%85%A5%E9%96%80%EF%BC%8B%E5%AE%9F%E8%B7%B5%EF%BC%BD%E8%A6%81%E6%B1%82%E3%82%92%E4%BB%95%E6%A7%98%E5%8C%96%E3%81%99%E3%82%8B%E6%8A%80%E8%A1%93%E3%83%BB%E8%A1%A8%E7%8F%BE%E3%81%99%E3%82%8B%E6%8A%80%E8%A1%93-%EF%BD%9E%E4%BB%95%E6%A7%98%E3%81%8C%E6%9B%B8%E3%81%91%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F-%E6%B8%85%E6%B0%B4-%E5%90%89%E7%94%B7-ebook/dp/B07729YVZC/ref=sr_1_1?keywords=%E8%A6%81%E6%B1%82%E3%82%92%E4%BB%95%E6%A7%98%E5%8C%96&qid=1695304993&sr=8-1)
- [「派生開発」を成功させるプロセス改善の技術と極意](https://www.amazon.co.jp/gp/product/B0772DM642/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i1)
- [はじめよう！ 要件定義](https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E3%81%86%EF%BC%81-%E8%A6%81%E4%BB%B6%E5%AE%9A%E7%BE%A9-%EF%BD%9E%E3%83%93%E3%82%AE%E3%83%8A%E3%83%BC%E3%81%8B%E3%82%89%E3%83%99%E3%83%86%E3%83%A9%E3%83%B3%E3%81%BE%E3%81%A7-%E7%BE%BD%E7%94%9F%E7%AB%A0%E6%B4%8B-ebook/dp/B00WHUP7UE/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=JPZG5BMM6E4S&keywords=%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E3%81%86+%E8%A6%81%E4%BB%B6&qid=1695305087&sprefix=%E3%81%AF%E3%81%98%E3%82%81%E3%82%88%E3%81%86+%E8%A6%81%E4%BB%B6%2Caps%2C354&sr=8-4)

## コードリーディング
- [コードリーディングの方法・コツ](https://qiita.com/miyagaw61/items/e47792be2204f4492258#%E8%AA%AD%E3%81%BE%E3%8E1%AA%E3%81%84%E6%8A%80%E8%A1%93)
- [スペックアウトによる設計仕様の理解](https://affordd.jp/previous/tech_documents/et2019_04.pdf)
- [コードリーディングのコツは極力コードを読まないこと](https://note.com/simplearchitect/n/n8cd219056536)