スケジュールの立て方について

## はじめに
こんにちは！

先日、社内の個人カリキュラムでWebアプリケーションを一人で作るという課題がありました。

以前、アプリケーションを作る過程で**期限を守りながら開発をする上で大切だ**と個人的に感じたことをこちらの記事で書かせていただきました。

https://qiita.com/MasanoriHarada/private/7449a5da36a801250278

その中で、大切なことの一つに**極力精度の高いスケジュールを作る**ということをあげました。

今回は僕が社内の個人カリキュラム中に実践していたスケジュールを作成・管理する際の方法について紹介したいと思います。

スケジュール作成・管理に悩む方へ少しでも参考になれば嬉しいです。

:::note warn
読み終えるのに10分くらいかかるかと思います。
ご興味がある方は、お暇な時にご覧いただければと。
記事の内容はあくまで個人的見解になります。
:::

## 記事の流れ

* なぜスケジュールを作る必要があるのか
* プロセスを具体化する
* 見積もり時間を決める
* 重い順に並び替える
* スケジュールに落とし込む
* 進捗管理する

順番に行きます。

## なぜスケジュールを作る必要があるのか
それは開発前にどんなリソースを投入するか、プロセスで実施するかを検討したり、開発中に進捗管理をするためですね。

現状のリソースで不足はないか、それぞれのタスクがどれくらい時間がかかって、いつ完了する見込みなのか、などを計画する必要があります。また、開発中の定期的な進捗管理により順調なのか遅延しているのかを早い段階で察知し、遅延しているなら対策を早期に立案する必要があります。

このようにスケジュールはプロジェクトを円滑に進めるために欠かせないコンパスのようなものであり、とても重要なものです。


今回、登場人物としてタロウ君という新人エンジニアがいるとします、タロウ君の状況は以下の通りです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/5768797e-72d0-a3a3-0ef2-c7de269109db.png" width=50%>

* todoアプリの開発を会社から依頼されている
* その要件は大きく分けてA、B、Cの3つ
* その要件全てを100％完遂することで完了とする
* 期限：4月30日
* 開発者：タロウ君（プレイヤー）のみ
* IT経験：プログラミングスクール6ヶ月通った経験のみ
* 開発に費やせる時間：平日3時間、土曜日5時間

この例を元に、自分が実践したスケジュールを作成・管理する際の手順を紹介していきます。

### プロセスを具体化する
それぞれの要件を満足するために何をしなければいけないか、なるべく具体的に洗い出します。

僕の場合は、処理が走る過程を頭で思い描きながら、順番にやるべきことをGoogle検索などで調べながら洗い出して行きました。 

例えば、先ほどのタロウ君のtodoアプリで要件Aが以下であったとします。

＜要件A＞
タスクが完了した件数と完了してない件数を該当のwebページに棒グラフで表示する
ただし、グラフは月ごとに横並びで表示。

あるwebページでユーザーが棒グラフのページに行くためのボタンをクリックした後、
この要件の処理の流れをめっちゃざっくり書くと

    1. 該当のrouteへアクセス
    
    2. routeからcontrollerにアクセス
    
    3. controllerからデータベースにアクセス
    
    4. データベースから必要な値を取得する
    
    5. 取得した値をcontrollerに渡す
    
    6. その値を該当webページのviewファイルへ渡す
    
    7.　　その値を使用して専用ライブラリの設定ファイルを読み込む
    
    8.　　グラフをweb上に表示
    
といった具合にプロセスが大体8項目あります。

次に、これらの中で実装経験がある内容と実装経験がない内容を洗い出して、それぞれの洗い出します。

##### 実装経験がある部分
* 項目1-6,8（計7項目）

##### 実装経験がない部分
* 項目7（計1項目）

項目7をさらに細分化すると特に以下の経験がないことを把握したとします。

* ライブラリを使って実装したことがない。（ライブラリの知識不足）
* そのグラフに関するライブラリの設定
* データベースから取得した値をJSが読み込める形式にする
（合計3項目）

このように、先ほど洗い出した8項目の処理を実装経験がある部分とない部分に分け、経験がない部分は具体的に何が分かっていないのかをできる限り把握します。

#### この作業を行う理由
見積り時間の設定の精度を上げるためです。次の項目で見積もり時間を決める際、経験がある部分は迅速に対応できると仮定して見積り時間を小さくし、経験がない部分は時間がかかるだろうから見積もり時間を多めに取ります。このように、それぞれのプロセスにかかる時間が多いのか少ないのかをざっくり区別できます。


この**実装経験がある・ない**は実際に開発を行う際に**時間がかからない・かかる**とリンクしていると思うので、それらを整理して見積り時間に強弱をつけることで実際の作業時間に近づくのではないかと思います。

### 見積もり時間を決める
それぞれの要件ごとに、どれくらい時間がかかりそうかを見積もります。先ほどの例で言うと、ざっくりとした処理の流れが8項目あり、それぞれの実装に何時間くらいかかりそうかを予測します。

ここで、実装にかかる作業を大きく2つに分解すると

* 調べる
* コードをファイルに書く

だと思います。**コードをファイルに書く時間**はせいぜい1時間以内で、圧倒的に**調べる時間**の方が長いと思います。


そのため、

**調べる時間＋コードを書く時間（1時間）＝ 要件一つあたりにかかる時間**


と推測できます。

そして、厄介なのが**調べる時間**を予測することです。
僕の場合は、実装経験があるものはそれぞれ0.5時間、経験がないものは項目ごとに+3時間すると仮定しました。

先ほどのざっくりした8処理の中で、実装経験がある処理が7つ、実装経験がなくて特に経験がない項目が3つありました。

それを踏まえて、要件：Aの実装にかかるであろう時間は以下の式で算出できると思います。

調べる時間：0.5時間✖️7個+（0.5時間+3時間)✖️3個＝14時間
コードを書く時間：1時間
合計時間：14時間＋1時間＝**15時間**

このように実装経験がある部分とない部分、それぞれに割り当てる時間を仮定して見積もりをするとそれっぽい時間を弾き出せます。


ちなみに、この要件Aは実際の個人カリキュラムの中の要件とほとんど同じであり、僕がこの実装にかかった時間は11時間であったため、見積時間と実績時間に大きな乖離はありませんでした。

また、上記で仮定した0.5時間とか3時間は人によって0.1時間だったり、5時間だったりします。そこは後で振り返りをした時に修正していけば良いと思います。そうしてどんどん自分の見積もりをブラッシュアップしながら、見積もり精度を上げていきたいですね。

これを要件ごとに全て見積もり時間を設定します。

タロウくんの場合のイメージは以下の通り、要件ごとにかかる時間を算出しています。

![おもりバラバラ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/372857e2-bed6-8638-ad6b-b74dc7d6b3d9.png)


### 重い順に並び替える
前項で要件ごとに見積もり時間を設定したら、見積もり時間が大きいものから取り掛かるように順番を並び替えました。イメージは以下の通りです。

![おもり重い順.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/50f14d9e-1aae-e77e-4e2d-841383dfff28.png)



なぜ重いタスクから実行するかというと理由は3つあると考えています。

#### 早期に対処できる
あるプロジェクトに自分が加入していることを想像してみてください。もしも、重いタスクが自分では手に追えない状況になった場合、それが早い段階で分かるとプロジェクトとして重いタスクの対処をどうするか早めに手を打てることになります。

これが軽いタスクから先に取り掛かって重いタスクを後に着手したとします。そうなると、重いタスクの対応が無理そうだと分かるのは、重いタスクを前にして判明した時期よりも後になる可能性が高いです。そうなるとプロジェクトとしても期限までの時間が短い中でどうするかを考えなければならず、解決策の選択肢が狭まります。選択肢が狭まると納期に間に合わないリスクだけでなく、焦って対応することによって納品物の品質にも影響を及ぼす可能性があります。

##### 失敗談

前職で機械設計の仕事をしていた時、ある案件で自分たちが設計した部品が現場で誤品であることが判明したことがありました。その対策にはこれまでに経験のない設計を要する内容でかなり重いタスクでした。お客様の期限調整の折り合いがつかなかった結果、1日で設計を終わらせて、3日後に対策品を納品するという超特急対応をしました。その結果、その対策品に不整合が判明し、関係者の方々にかなりのご迷惑をおかけしたことがありました。その後、毎日上司とナゼナゼ分析をしたことを今でも鮮明に思い出されます。苦行でした。。

このように時間がない中で焦って行動するとロクなことがなく、時間がない状況をなるべく作らないためにも、なるべく早く危険を察知できるようにした方がよいと思います。

#### 自分の成長のため
難しい課題に取り組むとどうやって実現するのかを考えたり、調べたりと試行錯誤することが多いので、自分を成長させることができると思います。もし難しい課題を後ろ倒しにした結果、時間が足りなくて難しい課題に取り掛かれなかったとしたら、成長する機会を失ってしまいます。そうなるともったいないので、その点からも難しい課題になるべく早く取り掛かりたいですね。

#### 仲間に迷惑をかけないため
本来自分が実施するはずだった難しい課題を期限間近でできないことが判明した場合、それを他の仲間が代わりに実施する可能性があります。そうなったとき、仲間はどんな感情になるでしょうか？少なくとも多少はイラッとする人が多いと思います。

この期限間近でキラーパスするかどうかはプロジェクトの方針によって変わってくると思いますが、僕は前職でこれを経験したことがあります。

##### 失敗談

当時前職に入社したての頃、僕は先に簡単なタスクから始めて、重いタスクを後回しにしていました。期限ギリギリになって間に合わないことが判明し、先輩に助けを求めざるを得ない状況になってしまいました。その時の先輩の形相は今でも忘れられません。そりゃそうですよね、先輩にも自分の仕事があるし、いきなり残業を強いられるわけなので。

この経験から極力早めに重いタスクを把握して、それから取り掛かるようにしました。

このような当時の僕みたいにならないように、仲間との関係をギクシャクさせないためにも難しい課題から取り掛かった方が良いと思います。

### スケジュールを作る
ここまで来ればあとは自分が一日にアプリ開発に費やせる時間と先ほど洗い出した見積もり時間を元に、以下の図の要領で開始日から期限日までに時系列で並べます。

今回タロウ君は平日3時間、土曜日：5時間（1週間で20時間）の時間を確保するとします。
すると、スケジュールは以下のように組めます。

![スケジュール1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670922/beb58487-d293-ca90-4f28-2eee9ea70dc1.png)

あとA,B,Cのような区切りの間に外乱の影響や各要件の遅れを加味してバッファを何日も設けるかも決めます。
僕の場合は大体１日程度のバッファを間に設けていました。

### 進捗管理する
スケジュールを作ったあとは定期的に現在の進捗とスケジュールを比較して、予定通りなのか、遅れてるのかを確認します。

僕の場合は、もし遅れてるなら、その時点でもう少し投入時間を増やした方がいいのか、どうにもならならいから期限を伸ばす相談を上長にするのか、判断するようにしていました。

また、進捗確認の頻度は最低でも1週間に一回は確認した方がいいかなと思います。
その方が遅れなどの問題が起こっている場合は早期に対応できるし、上司の方も安心すると思います。部下の進捗がどうなってるのか知らない状態で時が過ぎることほど怖いものはないと思いますので。

#### ちなみに

スケジュールを作る、管理する方法は、上記の通りで自分で一から作ったり、エクセルで作成するのもいいですが、個人的にはPRUMでも使用しているBacklogというアプリが使いやすくておすすめですね。

### 最後に

今回はスケジュールを作成・管理するために実践していたことを紹介させていただきました精度の高いスケジュールを立てることは簡単ではありませんし、日々の業務の中で計画・実行・反省を繰り返しながら精度を高めていく必要があると思います。
スケジュールを立てることに悩んでいる方にとって、この記事が少しでも参考になれば幸いです。

最後までご覧いただき、ありがとうございました！