この記事は私をシニアエンジニアにしてくれた「真のアジャイル開発」体験記の16日目の記事です。このアドベントカレンダーは「ある機能開発チームでスクラム, XP, DevOps を一度に実践したら真のアジャイル開発ができた」という内容です。執筆者は全てプログラミングをするパンダです。

ストーリー

本記事ではXPのストーリーの定義と自分たちのプロジェクトでの運用を紹介します。

ストーリーの定義

ストーリーとは、顧客に見える機能(フィーチャー)の単位を指します。例えばブログを作る場合、「ユーザーはブログを投稿できる」「ユーザーは一度公開したブログを非公開にできる」といった形で記述します。これによりプロダクトオーナー、デザイナー、エンジニアがユーザーのために何を作るかという観点でコミュニケーションを取れるようになります。機能を網羅した膨大な1000ページに及ぶ要件書よりも、このような一連のストーリーの方がビジネスメリットを認識しやすいです。

ストーリーに対しては、実装開始からデプロイまでにかかる時間をすぐに見積もります。XP本では時間で見積もる方法が紹介されていますが、現代ではストーリーポイントを使った見積もりが一般的です。

ストーリーポイントは時間ではなく、あるタスクのサイズを基準としてそれより大きいか小さいかの相対値で見積もりをする方法です。全てのストーリーのポイントを合計すれば、全体リリースのおおよその時期を見積もることができます。

ストーリーとその見積もりがあれば、どのストーリーを優先すべきかをビジネス的、技術的観点から議論しやすくなります。また、ユーザーのニーズに基づいてストーリーを再考しやすくなります。

例えば、前提条件がない状態で「ポルシェと軽トラックのどちらが欲しいか」と問われた場合、自分ならポルシェを選ぶかもしれません。しかし、来月自分で引っ越し作業を行う予定がある場合、軽トラックを選ぶ可能性がありますし、場合によってはレンタルで済ませるという選択肢も考えられます。さらに、引っ越し作業を業者に依頼する予定であれば、そもそも車は必要ないかもしれません。

機能ではなくストーリーを記述するとき、そもそも何でそれが必要なのかという背景や前提情報まで抑えることができます。このチームメンバー間のこのコミュニケーションのプロセスこそが重要なのです。

このようにストーリーを書いて見積もりを行ってチーム全体で共有することで、ユーザーの前提条件や制約に応じた適切なストーリーを選べます。また、ソフトウェアの価値を最大化するために優先順位を決める際にも大いに役立ちます。

ストーリーの運用

ストーリーの運用: ストーリーはユーザーを主語にして記述する

ここでは、ストーリーとストーリーポイントについて説明します。

ストーリーはタスクとは異なります。タスクは機能を実現するためにやるべき作業を指しますが、ストーリーはユーザーから見た機能の説明です。ユーザーがその機能を使ってできることを記述します。このため、ストーリーは一般的にユーザーストーリーと呼ばれます。

ストーリーを記述する際には、「ユーザーとして、Xができる(それはYだからだ)」というフォーマットを使用します。例えば、「ユーザーとして、ブログを投稿できる」「ユーザーとして、ブログを削除できる」という形です。

ユーザーという言葉が広義で曖昧になる場合には、ロールごとにストーリーを分解しても良いでしょう。

例えば、「レビュワーは、レビュー中ステータスのブログのみ閲覧できる。それは、執筆者が下書き記事をレビュワーに見せたくないからだ」や、「著者は、下書きステータスの記事のみ編集できる。それは、レビュー中に記事を編集するとレビュワーがどこまでレビューしたかわからなくなるからだ」といった具合です。

ストーリーの運用: 事前に完了条件を設定する

ストーリーを作成する際には、必ず前もって完了条件を記述しておく必要があります。どの条件を満たしたらそのストーリーが完了したとみなせるのかをチーム内で合意しておきます。

例えば「レビュワーは、レビュー中ステータスのブログのみ閲覧できる」というストーリーの場合、完了条件は次のように設定できます。

[完了条件]

  1. 管理者は、レビュワーというロールでユーザーを追加できる
  2. ブログ記事一覧画面でステータスを表示できる
  3. レビュワーは、下書きの記事を選択できない
  4. レビュワーは、レビュー中ステータスのブログを開ける

完了条件を事前に設定しておくことで、プロダクトオーナーは受け入れテストで迷うことがなくなります。事前に合意した完了条件を満たしているかをテストで確認すれば良いからです。また、受け入れテストを自動化する場合には、この完了条件をそのままテストケースの記述に利用できます。手動テストであっても観点は同じです。

さらに、完了条件を設定することでスコープクリープが起こりにくくなります。もしスコープが広がりそうになった場合は、別のストーリーとして切り出してその優先順位を決め直せば良いのです。

例えば、「ブログ記事一覧画面でステータスを表示する」という内容は、「ユーザーは、ブログ記事一覧画面で各記事のステータスが分かる」という別のストーリーに分けて管理できます。

こうすることで、後者のストーリーを完了させてから前者のストーリーに取り組むという依存関係を整理できます。

ストーリーの運用: ストーリーを作る前に調査タスクを作成する

調査タスクもストーリーから派生します。他チームに問い合わせたり、ドキュメントやコードを読んで開発に必要な知識を得るといった調査作業もタスクとして扱います。

これはスパイクと呼ばれるもので、ストーリーに着手する前に発生することがほとんどです。スパイクの結果を踏まえてストーリーの見積もりを正確に行ったり、複数の案(A案とB案など)のうちどれを採用するかを決定することもあります。

スパイクも漫然と進めるのではなく完了条件を設定して目的を明確にしておくことが重要です。自分たちのチームでスパイクを作るときはユーザーを主語にするよりも「XXを調査する」というタスク形式で記述していました。

次回はストーリーの後編をお届けします。

advent calendaragile
プログラミングをするパンダ
プログラミングをするパンダ (@Panda_Program)
Software Engineer

この記事は私をシニアエンジニアにしてくれた「真のアジャイル開発」体験記の15日目の記事です。このアドベントカレンダーは「ある機能開発チームでスクラム, XP, DevOps を一度に実践したら真のアジャイル開発ができた」という内容です。執筆者は全てプログラミングをするパンダです。

インクリメンタルな設計

本記事ではXPのインクリメンタルな設計の定義と自分たちのプロジェクトでの運用を紹介します。

インクリメンタルな設計の定義

インクリメンタルな設計とは、必要になった時に必要な分だけ設計をするというアジャイル開発を代表するプラクティスです。

ウォーターフォール型の開発では、事前にすべて設計をしてから開発に取り組みます。ウォーターフォールでは設計フェーズが完了すると実装フェーズに移ります。この場合、実装フェーズで得たフィードバックを設計フェーズに還元できません。一方、XPは設計をして実装してさらに再設計をしたり次の設計をします。部分的な設計と実装を繰り返すことにより、現場でのフィードバックを重視するのです。

システムは日々変化するビジネスニーズに柔軟に応えられなければなりません。この変化に柔軟に対応できる準備をし続けることが重要です。アジャイル開発では間違うことは問題ありません。間違ったことがまま進むことが問題なのです。間違ったまま進んでしまった後に多大な変更コストをかけて修正をするのではなく、毎日少しの労力をかけて設計を綺麗に保ち続けることが重要です。

また、間違っていることを間違っているというためにはチームの人間関係をしっかり築く必要があります。例え建設的な意見であっても間違っていると指摘することは心理的なハードルがあります。改善提案だとしても、他の人からは否定的な意見だと受け取られる恐れがあるからです。発言する側もそれを聞く側も、何かを指摘することで人を責めるのではなくコトの改善を考えているのだという信頼関係を先に構築していなければ、チーム内で自由な意見は出てきません。するとチームが間違ったままの方向で進み続ける可能性が高くなるのです。

XPはコードの設計や自動テストの継続的な改善という技術のプラクティスや、人間関係を円滑にするコミュニケーション重視のプラクティスを備えています。これらを実践することにより、設計や実装の変更コストを低く抑えられるのです。

インクリメンタルな設計を行うタイミングは、コードに手を入れる直前が適しています。すべての箇所を最初から細部にわたって設計するのではなく、仕様変更やメンバー間での認識と実装の乖離が明らかになった際に再設計を行います。それは時にコードをシンプルに保つためのリファクタリングという形で表れることもあります。

インクリメンタルな設計の運用

インクリメンタルな設計は、フィードバックを強く意識し続けなければ実践が難しい手法です。ソフトウェア開発をウォーターフォール型の「設計」「実装」「テスト」といった工程に分け、後ろの工程が前の工程へフィードバックを反映できない場合、インクリメンタルな設計の実践は困難になります。そのため、これはフィードバックを重視するアジャイル開発ならではのプラクティスだと言えます。

ここではインクリメンタルな設計について、アプリケーションコードの設計を中心に解説します。システムアーキテクチャやデータベースのテーブル設計については割愛します。

インクリメンタルな設計の運用: 設計を実施するタイミング

インクリメンタルな設計を行うタイミングは2つあります。それはコードの実装前と実装後に分けられます。

まず実装前に設計をするケースです。これは設計に着手する一般的なタイミングです。いくつか例を挙げます。

  • 大まかな仕様が固まって実装に着手可能になったとき
  • 誰かに設計レビューを依頼しなければならないとき
  • テストファーストでコードを書き始めるとき

このとき、設計の参考にするのは対象領域をよく知る人との会話やドメイン知識、ドメインモデル図、プロダクトオーナーが記述した仕様書、チームメンバーの知識や経験、さらにはプロジェクトの既存のコードです。これらを元にユーザーストーリーを満たす「動くソフトウェア」を作り上げます。

次は実装後に設計を行うケースです。一度設計と実装を終えているため、これは一般的に再設計と呼ばれています。

  • 実装が終わってテストをパスしているものの、コードスメル(コードの不吉な兆候)を感じてより良い方法で書き直したいとき
  • 仕様の追加や変更が発生して、既存の設計では実装が困難になったとき(リファクタリングが必要と判断されたとき)
  • ドメインの専門家やチームメンバーとの議論を通じて新たな発見をして、既存のドメインモデルが変更されたとき

他にも実装内容を整理して図やドキュメントとして記述している間に、より良い設計を思いつくこともあるでしょう。

再設計のタイミングに共通しているのは、設計に対するフィードバックが得られているという点です。設計と実装に対する良し悪しのフィードバックを得られたからこそ、再設計が必要だとわかるからです。一度実装を終えたコード、仕様変更、ドメインモデルの修正、図やドキュメントの作成・整理をきっかけに設計を見直しましょう。

インクリメンタルな設計の運用: 必要なときに必要な分だけ設計をする

優れた設計を目指す努力は重要ですが、最初から完璧な設計を作り上げることは現実的ではありません。ユーザーのニーズが変化し、それに応じてソフトウェアの仕様やソフトウェアに対する要求は変化するからです。このため、すべてに対して完璧な設計をするのではなく、必要十分な設計だけを行って先に進むことが重要です。

間違っていたら再設計すればいいのだと考えると、様々なところから情報を収集してあれやこれやと考えた結果、設計がいつまでも終わらない「分析麻痺(Analysis Paralysis)」や「完璧主義の罠」に陥ることを避けられます。

このように、インクリメンタルな設計とは何も設計をせずに実装に進むということではありません。設計をおざなりにするというのはアジャイル開発に対するよくある勘違いです。インクリメンタルな設計とは、実装直前に必要十分な設計を行うことで、コードの変更コストを小さく保つためのプラクティスなのです。

現在のIDE環境では、命名の変更やメソッドの切り出し、ディレクトリ構造の変更などのコストは大きくありません。ファイルやクラスのより良い分類方法を思いついた場合は、ディレクトリ構造やファイル名の変更を実施するべきです。TDDで実装を進めている場合、テストがすでに存在するため変更によるバグ混入の不安は軽減されています。様々な変更をした後にテストが成功していればリファクタリングは完了です。

ここまでアプリケーションコードでインクリメンタルな設計を紹介してきました。一方で、インフラ構成やテーブル設計、アプリケーションアーキテクチャに関してはインクリメンタルな設計が向かない場合もあります。これらは変更が不可能ではないものの、影響範囲が広く、変更コストが大きいためです。たとえば、アプリケーションをモノリス、モジュラーモノリス、マイクロサービスのどれで構築するかや、AWS上でやりたいことを実現するために何を使うのかなどは、前もって慎重に検討する必要があるでしょう。

クリーンアーキテクチャという書籍でボブおじさんは「変更できないソフトウェアはもはやソフトではなくハードウェアである」と述べています。インクリメンタルな設計を実践して必要な部分を継ぎ足していき、間違ったと分かったら勇気を持って改修したりリファクタリングをし続けましょう。このプラクティスを継続していればコードの変更コストは低く抑えられていることでしょう。

次はストーリーの定義と運用を紹介します。

advent calendaragile
プログラミングをするパンダ
プログラミングをするパンダ (@Panda_Program)
Software Engineer

この記事は私をシニアエンジニアにしてくれた「真のアジャイル開発」体験記の14日目の記事です。このアドベントカレンダーは「ある機能開発チームでスクラム, XP, DevOps を一度に実践したら真のアジャイル開発ができた」という内容です。執筆者は全てプログラミングをするパンダです。

テスト駆動開発

本記事ではXPのテスト駆動開発の定義と自分たちのプロジェクトでの運用を紹介します。

テスト駆動開発の定義

XP本は「テストファーストプログラミング」というプラクティスを紹介していますが、その内容は明らかにTDD(テスト駆動開発)を指しています。両者の違いを簡単に説明すると、テストファーストプログラミングは「テストを先に書いてから実装する」ことを指し、TDDは「クラスの形すらもテストから導き出す設計手法」を意味します。以下ではTDDとして解説を進めます。

TDDを実践することで「これも必要かもしれないから先に実装しよう」というYAGNI原則が指摘する問題を避けることができます。テストが通ればその時点で実装が完了したと判断できるためです。プロジェクトにまで広げるとスコープクリープ(Scope creep。プロジェクトのスコープの肥大化)の問題にも一部対処していると言えるかもしれません。

また、先にテストを書くことで、自然とテストしやすいクラスを設計できるようになります。その結果、コードにテストが含まれることでチームメンバーからの信頼を得られるでしょう。

さらに、ローカルでテストを実行すればすぐにフィードバックが得られるため、実装した処理が期待通りに動いているかを即座に確認できます。「このような入力値が来たらバグるかもしれない」と不安に思った場合には、そのテストケースを追加して挙動を確認することが可能です。もしテストが失敗した場合は必要な追加実装を行い、テストが通ればそのテストは残しておきましょう。

あなたが追加したテストケースは、将来チームの他のメンバーが抱くかもしれない不安を解消することになるのです。

テスト駆動開発の運用

TDDの具体的な実践方法についてはTDDの解説記事をご参照ください。 TDDはプログラミングスタイルの一つであり、一人でも始められます。ただし、ペアプログラミングでTDDを行う場合にはいくつかの工夫が必要です。

まずテストを先に書くことを徹底する必要があります。最初は意外にこれができません。特に相手がTDDにどの程度積極的か分からない場合に困ることがあります。私自身も開発に着手した当初は「どんな処理にすると良いでしょうか」と話しながらプロダクションコードを書いてしまっていました。TDDが好きではあったものの、他の人に強制するのは良くないと考えていたため、中途半端になっていたのです。

しかし、あるスプリントの振り返りでチームメンバーが「テストファーストを徹底できていない。プロダクションコードから書き始めてしまったら、テストから書こうとお互いに声を掛け合おう」と提案してくれました。この提案を受けてから、チーム全体がテストからコードを書くスタイルを確立しました。このように、一度スタイルを決めたら中途半端にせず徹底することが重要です。

設計が必要な場合には簡単な図を描いて共有することが有効です。TDDはテストを先に書きながらクラス設計を行う手法であり、事前に設計を完璧にする必要はありません。ただし、設計はドメインモデルに基づいて行われるため、頭の中にある考えを言葉や図にして形式知化しないと相手に伝わりません。

例えば、ブログのシステムを作る場合を考えます。データベースに保存されたMarkdownのテキストをHTMLに変換する機能を実装するとします。このとき、「Markdownを渡したときにHTMLに変換する」という名前のテストを書きます。テストで「# が h1 タグになる」というアサーションを追加すると、ペア同士で「## はどうする?」「**はどう処理する?」「データベースから値を取得する必要がある」といった会話が発生します。その際、考えている内容を簡単な図で表現すると効果的です。

このような図は、チーム外に提出する正式な設計図である必要はありません。ペア相手との間で設計案を共有し、フィードバックを得るためのもので十分です。この図を描くのに5分もかかりません。図を基に議論を重ねることで、より良い設計にブラッシュアップできます。

頭に浮かんだことを積極的に話すことも重要です。不安や疑問点、例えば「このクラス名で良いか」「メソッド名は処理内容を的確に表しているか」「メソッドの引数や順番は適切か」など何でも共有します。クラスやメソッドの分割についても自分の意見が正しいと思い込まずに相手の意見を聞いて考えます。

自分からは「こんな簡単なことを聞いたらバカにされるかも」といった不安を捨て質問をしましょう。また、相手を尊敬して謙虚な姿勢で他の人のアイデアを取り入れることが大切です。自分たちの会社の採用チームを信頼して、社内には攻撃的な態度を取る人がいないと考えましょう。万が一嫌なことを言われた場合はマネージャーに相談すれば良いのです。まずは相手を信頼して行動することが大切です。

テスト駆動開発をペアプログラミングで実践することでチームメンバー同士の信頼感が高まります。それがより良い設計と実装に繋がります。TDDとペアプログラミングという最高のコミュニケーションプロセスを通じて、チーム全体で効率的かつ信頼性の高い開発が可能になるのです。

TDDで開発した結果、自分たちの書いたコードのテストカバレッジは96%を達成することができました。

次回はインクリメンタルな設計の定義と運用を紹介します。

advent calendaragile
プログラミングをするパンダ
プログラミングをするパンダ (@Panda_Program)
Software Engineer

この記事は私をシニアエンジニアにしてくれた「真のアジャイル開発」体験記の13日目の記事です。このアドベントカレンダーは「ある機能開発チームでスクラム, XP, DevOps を一度に実践したら真のアジャイル開発ができた」という内容です。執筆者は全てプログラミングをするパンダです。

同期レビュー

本記事では同期レビューの定義と自分たちのプロジェクトでの運用を紹介します。

同期レビューはXPのプラクティスには含まれていません。「トランクベース開発」で紹介されているプラクティスの一つです。しかし、私個人の意見としてXPの「全員同席」や「ペアプログラミング」といったプラクティスを実践している場合、同期レビューは自然と導き出されるアクティビティであると考えています。

同期レビューの定義

同期レビューとは、その名の通り「PR(プルリクエスト)が作成できたのでレビューをお願いします。疑問点はその場で解説するので、一緒にPRを見てください」と同期的に人に依頼することを指します。この際、レビュワーはPRをすぐに確認してその場で気になる点を指摘します。指摘事項が解消されてレビュワーが納得すれば即座に承認(approve)を行います。

非同期的なレビュー依頼のようにSlackで「レビューをお願いします」とメンションを送って相手の手が空くのを待つのではなく、PR作成が完了した段階でその場ですぐに確認してもらうのが同期レビューの特徴です。この方法により、レビューの時間を効率化し、チーム内で迅速なフィードバックと進捗が可能になります。

同期レビューの運用

ペアプログラミングが中心のチームでは、同期レビューを次のように実施しています。ペアプログラミングでのコーディングが一区切りついたらプルリクエストを作成し、別の二人のペアにGather上で話しかけてレビューを依頼します。依頼を受けたペアは作業の手を止め、一人がPRのページを開いて画面共有を始めます。この結果2つのペア、つまり4人のエンジニアでコードレビューを行う形になります。

レビューを依頼されたペアは、通常のコードレビューを実施します。コードを読む際に疑問があれば、その場でレビューを依頼したペアに尋ねます。質問を受けたペアは、コードを書いた背景や機能の仕様、意思決定時のトレードオフを口頭で解説します。

ペアプログラミングを実践しているため、もちろん一定のコード品質は担保されています。しかし、そのペアの二人では気づかなかった視点や設計の指摘を受けることがあります。

同期レビューの小さな指摘の対応

指摘内容はごく一般的なものです。例えば、タイポや変数名の改善、コードコメントの追加などです。修正が簡単なものはレビュー中にすぐに直してしまいます。

コードを書いたペアも一緒にPRを確認しているため、たまに人から指摘される前に自分で「もっと良い書き方がある」と気づくことがあります。それが興味深いです。人と一緒に見ることで自分のコードをより客観的に見ることができるのでしょう。

「この人はここを指摘するだろうな」という視点で自分のコードを見ると、その人の実際の指摘より先回りして自分のコードの粗に気がつくのです。人と一緒に同じコードを見ているだけで、他の人の視点をインストールしているのです。

同期レビューの大きな指摘の対応

一方で、クラスの責務に関する指摘など少し大きなリファクタリングが必要な場合は、その場で修正せずに先に承認(approve)をもらってリリースします。

動作自体には問題がないためデプロイしても不具合は発生しません。デプロイ後すぐにリファクタリングを開始し、遅くとも翌日午前中までにもう一度同期レビューを受けてapproveをもらってリリースします。

このプロセスにより、「リファクタリングを後回しにする」という状況が防げます。この手法は後述するインクリメンタルな設計にも関連しています。

同期レビューにかかる時間

同期レビューの時間は短い場合は10分程度ですが、最長で30分かかることもあります。特に、実装が膨らみすぎた場合は20~30分ほどかかることが多いです。そのため、ペア内で「実装が膨らんできたので、そろそろレビューに出しましょう」といった判断を早めに行うよう心がけています。この結果、PRのサイズは比較的小さく抑えられる傾向があります。

また、同期レビューによりレビュー待ちの時間がなくなりました。その結果、常に一つの作業に集中できるため、マルチタスクを避けられます。さらに、仕掛かり中のPRの数は2~3つに収まり、管理がしやすくなっています。

同期レビューにはコミュニケーションコストの削減という効果もあります。具体的には、同期レビューを実施した場合、PRのコメント数は非同期レビューの場合に比べて少ないと感じます。

非同期レビューのPRのコメントは、ペア内での承認(LGTM)や指摘事項を忘れないための簡単なメモ程度で済みます。。また、口頭でコードを説明するため「ここのコードの意図は何ですか」といった実装しゃがヒヤっとするコメントや、それに返答するための説明を長々と書く必要がありません。

概要はPRに記載しており、コード内に仕様が表現されている場合でもコードコメントを追加して補足する程度で済みます。テストコードもあるため、メソッドの挙動はそちらを参照して理解してもらえるようになっています。

さらに、同期レビューによってペアの進捗状況やスプリントゴールの達成に支障がないかまで把握することができます。

ただし、コードを実装した側とレビューした側では理解度に差が出ることがあります。この差を埋めるため、チームではポンチ絵程度の図をFigJamで作成し、「モデリング図」や「データフロー」としてプルリクエストに添付しています。

この図にはデータの流れなどを描き、処理の流れを大まかに把握できるようにしています。これによりチーム内でキャッチアップが必要な場面でも、「ゼロから全てを理解する必要がある」という状況を回避できます。

次回はテスト駆動開発の定義と運用を紹介します。

advent calendaragile
プログラミングをするパンダ
プログラミングをするパンダ (@Panda_Program)
Software Engineer

この記事は私をシニアエンジニアにしてくれた「真のアジャイル開発」体験記の12日目の記事です。このアドベントカレンダーは「ある機能開発チームでスクラム, XP, DevOps を一度に実践したら真のアジャイル開発ができた」という内容です。執筆者は全てプログラミングをするパンダです。

ペアプログラミング

本記事ではXPのペアプログラミングの定義と自分たちのプロジェクトでの運用を紹介します。

ペアプログラミングの定義

ペアプログラミングとは、一つのマシンの前に二人のプログラマが並んでコードを書く開発手法の一つです。このプラクティスは、元々Wikiの考案者であるWard Cunningham氏とKent Beck氏が一緒に行っていたエピソードで知られています。このときの様子は、Kent Beck氏の記事にわかりやすく記述されていますので、以下に引用します。

最初は、Wardがプログラミングして、私はそれを見ていました。数日後、彼が気づく前に、私はタイポを発見しました。数週間後、私は名前付けと設計の矛盾点を見つけました。それがシンプルにするきっかけとなりました。 プロセスが進むにつれて、私たちはキーボードとマウスを交換していることに気づきました。ゾーンに入っているときは、ひとりがキーボードを操作して、もうひとりがマウスを操作していました。最終的なコードには一貫性があり、どちらがどの部分を書いたのかわからないほどでした。 どのように書くべきか意見が分かれるたびに私たちは手を止めて、問題について議論していました。 「エンジニアのコーチング」 Kent Beck(太字は筆者)

このようにペアプログラミングでは二人一組のペアとなり、一つの対象に対して分析や設計、テスト、リファクタリングを行います。自分たちのチームでもペアプログラミングを推奨していますが、必須にはしていません。一人で作業を進める方がいいのであれば、そのメンバーを尊重して任せています。特に調査や設計といった作業は一人で集中して取り組みたいと考えるプログラマが多いです。

ただし、調査結果や設計案をペア相手に共有することですぐにフィードバックが得られます。これにより、実装後に「設計を見直した方がいいですね」という手戻りが発生するのを防ぐことができるのです。

ペアプログラミングの紹介

ペアプログラミングを行うツールとして、音声通話にはGather、コード編集にはPhpStormのCode With Meを使用しています。仮にVSCodeを使用していればLive Shareを利用していたでしょう。また、XP本には「相手のパーソナルスペースを考慮する」「強い香水をつけない」「風邪を移さないために病気の時は休む」などの配慮が記されていますが、リモートでペアプログラミングを行う場合はこれらをあまり気にする必要がありません。筆者としてもリモート環境の方が心理的にペアプログラミングを実施しやすいと感じています。

最初の頃はペアがほぼ固定されていたため、ペアを組み替える目的でSlackのワークフローを作成しました。このワークフローは「今から⚪︎⚪︎しようとしています。誰か一緒にやりませんか?」と人を募る投稿をするものでした。

ドライバーとナビゲーターの役割は明確には分けていませんでしたが、通常はCode With Meのホストがドライバーとなり、コードを書いてコミットしています。XP本には数時間ごとにペアを交代することが推奨されていますが、自分たちのチームでは厳密には運用していません。

ホストがコミットしたブランチをナビゲーターがプルして開発し、また交代するというのが大変だったからです。この煩雑さを軽減するペアプロ用のツールがあるのは調べて知りましたが、結局導入せずでした。なのでかなりの時間ホストがコードを書き続けることもあります。

また、3人でのモブプログラミングも試してみました。しかし、レトロスペクティブで「2人が話したりコードを書いている間、3人目が貢献できていないと感じる」といった課題が挙がりました。そのため、このチームではモブプログラミングをやめてペアプログラミングに専念することにしました。

ペアプログラミングの利点としては、リアルタイムのコードレビューと仕様の抜け漏れチェックが挙げられます。また知識の伝達の場にもなるため、互いに知識不足を補い合うことができます。意思決定が必要な場面ではペア内で議論を行い、トレードオフを考慮したうえで二人が納得できるアイデアを採用します。このプロセスを経ることでコードの品質が向上するのです。

ただし、ペアプログラミングでは考えていることを常に相手に伝える必要があるためかなり疲れます。コードを書いている側は喋り続けなければならないからです。

自分たちのチームでは、朝の11時から11時45分までと、昼休憩後の14時から夕会前の18時45分までペアプログラミングを行っています。ペアプロは午後に5~6時間も続けると頭が回らなくなり、言い間違いや些細なリファクタリングにすら取り組む気力がなくなることがあります。

そうなる前に仕事を切り上げてリフレッシュし、翌日に続きをするのが良いと考えています。このように「余裕を持って仕事をする」ことが、長期的に見ると重要です。これがXPのプラクティスである「いきいきした仕事」や「ゆとり」に繋がります。

なお、日中に1on1やミーティングが予定されている場合には、作業を一時中断するか、一人でできる部分まで進め、相手が戻ってきた際に困っている点を相談する形で進めています。

次回は同期レビューの定義と運用を紹介します。

advent calendaragile
プログラミングをするパンダ
プログラミングをするパンダ (@Panda_Program)
Software Engineer