チーム開発における試行錯誤

# チーム開発におけるあれこれ

こんにちは！開発部所属の@k_mattunです。
この記事は、All About Group（株式会社オールアバウト） Advent Calendar 2020 18日目の記事となっております。

## はじめに
みなさん、仕事を進める際にどんな形で開発をされてますか？
私は今、チーム開発でプロジェクトを進めています。

今回はチーム開発の仕方で生まれた課題や、その課題に対する試作をご紹介します。
その試作のよかったことや悪かった事、現在の開発の進め方などをいい感じに話せればなと思います。

また、オンラインだからこその働き方なども軽く紹介するつもりなので是非ご覧ください。

## コミュニケーションが少なく、各々別レーンでタスクを進める
まず軽く今の仕事を説明しますが、多数のシステムと連携するwebシステムの開発を行っております。

最初に必要な機能を洗い出した後は分割したタスクを各々が進める、チームだけど個人開発っぽい進め方をとっていました。
一応朝会を行っていて、毎日の進捗共有など行っていましたが、それ以外はあまり会話などもなく黙々と作業を進める感じです。

### 発生した問題
**タスクに対する認識のズレが生じる**

タスクを洗い出す時点で本当はズレがあるのですが、それに気づかず各々のイメージで実装していくため、そのズレが大きくなっていって取り返しのつかない事になります。タスクの粒度にもよるかと思いますが、認識がずれた状態で進めてしまうと作った機能をまた一から作り直す・・・なんて事になりかねません。

**レビューに時間がかかる**

レビュアーは開発者の思考の過程がわからないためなぜその実装にしたのか確認する、もしくは同じ思考の過程を辿る事になるので純粋に時間がかかります。
これが複雑なロジックのレビューとなると、正直解説が欲しくなります。

また、レビュアーも別のタスクを進めているため、プルリクを作成してからレビューされるまでの空白の時間も発生します。
要するに待ちの時間ができちゃいます。

**狭い視野での実装になりがち**

実装者1人の知見やアイディアしか反映されず、偏った実装になりがちです。

**知見の共有がされない**
タスクを進める上で得た知見や経験などをチームで共有しずらいため、チーム全体の開発力向上が難しくなります。

### 試した事
> 各々別レーンでタスクを進める

この問題に対して、私たちはペアプロ、モブプロで作業を行うように開発の進め方を変更しました。
この結果、タスクを取り掛かる前に認識のすり合わせを行うようになり、実装する前の早い段階でズレを無くすことができました。
レビューに関しても、お互いコードを書きつつ同時にレビューして合意しながら実装する事ができるので、レビューのコストが格段に減りました。

また、ナビとドライバーで別れてやるため必然的にコミュニケーションが増えます。
その結果、お互いの知識やアイディアによってブラッシュアップされたより良いものができ、かつ知見の共有もできるようになりました。

## チームの振り返り1ヶ月に1回(1時間)とかで、振り返る頻度少ない
毎日朝会はしますし、軽く問題点の共有だったりとコミュニケーションをとっていましたが、YWTとかKPTとか、本格的に行うチームの振り返り活動は月に1度の頻度で行っていました。

### 発生した問題
**問題に直面しているのかわかりづらい**

朝会は、短時間なためどうしてもタスクの進捗共有会になりがちです。
そのため、今こういう問題が発生してます。とか開発の進め方でここが気になってます。とか。
他にも、今のチームのここって課題じゃない？みたいな話はあまりできません。

その結果、今チームメンバーがどんな問題を抱えているのか？個人やチーム、それぞれが抱えている課題などに気づくことができません。

**改善活動の周期が長くなりがち**

日々の業務で感じる課題って、あると思います。
その課題をその時にチームに共有してすぐにアクションを決めれればいいのですが、大体タスクを完了させる事に意識が向きがちなので、その瞬間にアクションを起こすことはありません。そして、この課題を共有する場はチームの振り返りの場になる事が大体だと思います。

振り返りの頻度が少なくなると、改善活動のサイクルが長くなります。課題に気づかないし、課題の解決の機会も減るため、チーム力の向上は難しくなります。

### 試した事
> チームの振り返り1ヶ月に1回(1時間)とかで、振り返る頻度少ない

この問題に対して、毎日午前の終わりと午後の終わりにそれぞれ短時間での振り返りを行うようにしました。振り返りといっても10分程度で行います。

この振り返りは決まった形はなく、様々なやり方で行っています。
１例を挙げると、午前・午後それぞれやった事、感想(よかった事や気になった事)、午後、もしくは明日やることを宣言します。

こうすることで、メンバーが感じた感情であったり学び舎気付き、チームが抱えている課題などを可視化できます。
良いところは伸ばす活動を、悪いところは改善する活動を半日という短いペースで行うことができます。

重要なのは、普段の通常業務では流れがちな、気付きや課題感を引き出して、個人・チームが抱えている感情や課題を発見するきっかけ作りだと思います。

チーム力向上を力説していますが、この振り返りで相手がどう考えているのか、どういう理想を持っているのかなど知る機会ともなります。
チームの立ち上げ当初とか、チームメンバーを知って自分を知ってもらうという、コミュニケーションの活性化にも繋がると思っています。

## 見積もりが大きくずれる
システム要件を考慮して、タスクの洗い出しを行った後、工数をつける作業があります。
タスクの洗い出しは主に1人が行い、工数をつける際はチームメンバー全員で話し合いながら設定しました。

### 発生した問題

**タスクに対する認識がずれる**
工数をつける際に、メンバー全員で集まってタスクについて話し合いが行われるのですが、洗い出しの作業を1人がやってしまっていたので、メンバー間でタスクに対する認識にズレが生じてしまいました。

ズレがある状態で話し合いが進められるため、工数の話し合いでもズレが生じてしまいました。

**具体的な基準がなく、想定した工数と実際の工数で差が生じる**
上記の問題は一旦置いておいて、あるタスクの工数を決める際に具体的な基準値等がなく、各々メンバーの過去の経験から推測して工数を決めておりました。
また、工数をつける際に誰がこの機能担当するかも一緒に決めていたので、その人がやるならこれぐらい・・・みたいな数値を出していました。

そのため、別の人がそのタスクをやる事になった場合全然参考にならない予測工数となってしまってました。

**１つ１つのタスクが大きくなりがち**
当たり前ですが、見積もりってタスクの規模が小さければ小さいほど精度が上がり、大きければ大きいほど振れ幅が上昇しますよね。
私たちは、タスクの洗い出しにかける時間が少なく(当初は少ないと思っていなかった）、細かい機能まで洗い出せずに規模の大きいタスクとして洗い出していました。

極端な例ですが、ユーザーにフォームを入力してもらって、そのデータを元にDBの更新を行いメールを送信して別画面を表示する機能があるとします。

もしこれをタスクに分解するなら

- ユーザーが画面で入力できる
- 入力されたデータを元にデータの更新を行う
- メールを送信する
- 画面を返す

とかになっていたと思います。
しかし、実際は入力データのバリデーションが抜け漏れています。
また``入力されたデータを元にデータの更新を行う``に関してはController、Service、modelを作る必要があり規模がかなり大きくなっています。

このように、見えていなかった機能が出てきたり１つのタスクが大きい事によって工数に差異が生じる原因となりました。

### 試した事

> 見積もりが大きくずれる

今まで洗い出したタスクと工数は一旦おいておいて、再度見積もりをしなおしました。

前回の教訓を生かし、タスクの洗い出しは1日とか大きめに時間をとってチームメンバー全員で行いました。
洗い出されるタスクに対する認識のズレを小さくする目的と、洗い出し忘れていた機能を減らす目的があります。

具体的な手法としてプランニングポーカーを導入してみました。

#### プランニングポーカー

プランニングポーカーとは、数字の書いてあるカードを使って、あるタスクについて話し合いながら作業工数を決める工数見積もりの手法です。
規模を表すストーリーポイントと呼ばれる、複数の数字を元に、それぞれのタスクはいくつのストーリーポイントだ！と話し合いながら算出します。
ストーリーポイントは``1、2、3、5、8、13``の6つです。

具体的な流れは以下の通り。

**1. 基準のタスクを決める**

まずは基準となるタスクを決めます。このタスクは、メンバー全員が既に知っている（実装経験がある）タスクを選びます。
私たちの場合は、過去に実装しためちゃくちゃ簡単でもないけどめちゃくちゃ難しくもない、要はバランスのよかったタスクを選択しました。

そのタスクに対しポイントを5と設定しました。

**2. 見積もるタスクと、そのタスクに対するストーリーポイントを決める**
次に、見積もるタスクを選択し、メンバーは各々タスクに対してストーリーポイントを決めます。
この際、先ほど話し合った基準のタスクと相対的にどのくらいの規模か考え、ストーリーポイントを決めます。

**3. 決めたカードを出す**
>見積もるタスクと、そのタスクに対するストーリーポイントを決める

で決めた値のカードを、みんな一斉に出します。

**4. 選択したポイントの理由を話す**
場に出したカードのポイントが全員一致していたら、そのポイントを採用します。
カードの数がバラバラの場合は、タスクに対する認識がずれている可能性が高いので、理由を順番に確認していきます。

**5. ポイントを選び直す**
> 選択したポイントの理由を話す

ここで話した理由を踏まえて再度選び直し、全員で場に出しなおします。
カードの数が揃うまでこれを繰り返します。

この結果、メンバー間のタスクに対する認識のズレをかなり減らす事ができました。
ポイントの理由を話す際に、具体的な実装の話とかするので設計しながらタスクを洗い出せるのがかなりよかったです。

また、``13``とか大きいポイントが出た場合はタスクの規模が大きすぎるので、タスクを分割する活動ができます。

もちろん、ここまでしたら完璧に工数割り出せるってことはありませんが、ずれる振れ幅をかなり小さくする事ができました。

## オンラインでの工夫
随分と長くなってしまいましたが、今まで紹介してきた問題とその対策を経て私たちのチームは以前と比べてコミュニケーションの量が格段に増えました。
また、ペアプロ導入などよりチーム開発を行うようになりました。

そこで重要になってくるのが円滑なコミュニケーションです。
現在、弊社は基本的にリモートワークで仕事を行っています。そのため、ペアプロやるにしてもオンライン上でのコミュニケーションとなってしまいます。

オフラインの場合は、ナビとドライバーが隣り合って座り、1台のモニターとPCを使って開発を行うため、会話はもちろん画面を指差しながら実装について議論を行うことができました。

オンラインでペアプロを行う上で発生した問題点と対策も紹介できればと思います。

### 問題点
**画面共有の場合実装に対して議論が難しい**

以前なら指を指しながら議論できていた事が、オンラインだと全て言葉で説明しなければならず、上手く伝わらないといった事が発生しました。

**意思疎通が難しくなった**
これはペアプロに限ったことではありませんが、オンラインになると今まで伝わっていた事が伝わりにくくなったり、相手がどんなリアクションをしているのかわかりずらく、コミュニケーションコストがかかってしまいました。

### 試した事
上記の問題に対して、試したことは2つあります。

**1. Slackやmeets、zoomなど通話アプリで通話を繋げっぱなしにする**

他の会社の方にこれを言うと驚かれる事が多いのですが、これが意外と有効です。今の開発はペアプロ、モブプロなどチームで動く事が多く、基本的に業務時間の殆どを喋りながら過ごしています。
話しながら実装し、話しながら設計を行うため、必然的にこの手法をとる必要がありました。

かといって、離席する時はマイクをミュートにしますし、自由に出入りできるので正直オフィスで横に座りながら仕事をするのと然程変わりません。また、会議や振り返りなど、実装ではなくコミュニケーションが主となるような時間の際は、なるべくカメラをオンにしています。

こうする事で、困っている時にすぐアドバイスを聞く事ができますし、マネジメントする立場の人は作業雰囲気や内容、進捗などを把握する事が可能となります。

**2. LiveShareの導入**

オフラインでは、同じのモニターとPCを使って同一の環境で実装できていましたが、オンラインではそれが難しかったです。

しかし、LiveShereを導入することでそれが可能となりました。
まず、同一のファイルを編集できるので、あれ、とか何行目の~~みたいな説明がカーソルを上手く使って議論できるようになります。
また、言葉での説明が難しい時にさっとコードを書いて説明するとかできるようになりました。

他にも、ターミナルもシェアするのでナビとドライバーの交代の際にコミットして、プッシュしてプルしてきて・・・みたいなのもなく切り替えやすいです。
フロントの開発においても、シェアサーバー機能を使えば、ローカルでたてたDockerにアクセスすることも可能になりデバック作業などお互いできるようになります。

## まとめ
本当はもっと書きたいこともありますし、もっと上手く伝えたいのですが、文章が長くなりすぎるのでこのぐらいとさせてください。
いろいろ失敗とか経験して、自分自身の振り返りも含めてこの記事を書かせて頂きました。

ここで紹介したのは私1人で導入したわけではなく、都度メンバー全員で話し合って改善してきたものになります。
また、あくまで一例であってこれが正解とか全く思ってないです。プロジェクト、メンバーなどによって適した進め方があると思います。

ただ、ここで紹介した話がどこかのチームで役に立てばいいなと思います。
また、うちはこうしたよ！とか、こういう場合こうするといいかも的なのあったら是非教えてください。

それでは、読んでいただきありがとうございました！