モブプロ活用事例 - Java + Spring Bootを使用した新規アプリケーション開発

OGP

こんにちは。ECプラットフォーム部マイグレーションチームの半澤です。

この記事では、Java + Spring Bootを使用したアプリケーション作成時にモブプログラミングを活用した事例をご紹介します。モブプログラミング未経験の方や、これから実施を考えている方の参考になれば幸いです。

目次

はじめに

ZOZOTOWNのシステムにはレガシーな部分が多く存在しており、全体的なシステムリプレイスを進めています。その中でサーバーアプリケーションのリプレイスを行うために発足したのがマイグレーションチームです。

現在はキャッシュストアのリプレイスや、新規マイクロサービスの立ち上げ、立ち上げたサービスのJava未経験チームへの引き継ぎなどを行っています。

マイグレーションチームでは、プロジェクトごとに担当者をアサインするリソース効率を重視した働き方がこれまで主流でした。リソース効率を重視すると、メンバーはそれぞれ特定の業務のスキルに特化したエキスパートとなります。ある特定の業務の仕事量が増えた場合、その数少ないエキスパートだけでは仕事をこなせなくなり、遅れが生じ全体のボトルネックとなってしまいます。

チームとしては、チームワークや思いやりを大切にし、お互い高め合うような働き方をチームの目標として掲げています。しかし、実際は業務知識が各個人で分散しているため協力しにくく、プロジェクトの規模によっては特定のメンバーのみ残業が発生するという課題を抱えていました。

そんな中、この問題を一気に解決したのがモブプログラミングです。

モブプログラミングとは

モブプログラミングは、リソース効率ではなくフロー効率を高めて早く機能をリリースすることを目標としています。フロー効率を高めることで、メンバー全員が業務知識を持ち、特定のメンバーへの依存度を下げることができます。その結果、負荷の分散だけでなく、特定のメンバーが突然稼働できなくなっても開発の継続が可能です。

これが実現できれば、上記のようなチームが抱えている課題を解決してくれそうです。

モブプログラミングの手法は、ペアプログラミングから発展したもので、3人以上の人々が1台のコンピュータの前に座って協力しながら問題を解決していきます。

モブプログラミングは「タイピスト」と「モブ」の役割があります。ひとりがタイピストとしてモブの指示を理解しタイピングを行い、その他はモブとしてタイピストへ指示を出します。タイピストは定められた時間がきたら次の人へ交代します。

詳細は、モブプログラミング・ベストプラクティス がとても参考になるのでご興味のある方はぜひご一読ください。

このようなメリットから、今回のプロジェクトでは実験的にモブプログラミングを実施することになりました。

プロジェクトの概要

私たちのチームでは、主にJava + Spring Bootを使用したアプリケーションを開発しています。今回のような新規マイクロサービス立ち上げ時は、既存のアプリケーションで使用している基盤を元に作成していました。

しかし、その参考元となる基盤も構築から既に3年経過しており、改善の余地が出てきたため、この機会にアーキテクチャやツール・ライブラリの見直しを行うことになりました。

開発メンバーは私を含め4名です。また、初回作成するAPIは同じような処理を行うGET、POST、PUTのエンドポイント計11本です。

開発は下記の流れに沿って進み、モブプログラミングは基盤構築のフェーズで実施しました。

  1. アーキテクチャ設計
  2. 基盤構築(モブプログラミングの実施)
  3. API実装

順を追って説明します。

アーキテクチャ設計

既存サービスの基盤 はレイヤードアーキテクチャを採用していました。詳細は以下の記事をご覧ください。 techblog.zozo.com

しかし、今回の新しい設計ではDDD + オニオンアーキテクチャを採用しました。オニオンアーキテクチャを選択した理由は、インフラストラクチャ層がドメイン層に依存せず、DDDが推奨するアーキテクチャの中で一番理解しやすい形だからです。

今回作成するサービスは、ビジネスロジックが多く入りこみ、機能の特性や既存システムの縛りによって複数のデータベースを使い分けることとなります。複雑なビジネスロジックをレイヤードアーキテクチャのサービス層におくとサービス層が膨らみ、変更の際に影響範囲が分かりづらいという状況が予想されます。

また、将来データベースの切り替えも想定されるため、インフラストラクチャ層に依存することを避けたいという事情もありました。

DDDの経験者は1名で、他のメンバーは文献を読み知識はあるものの、実務レベルでは未経験です。チャレンジングではありましたが、変更に強いシステムを作るためにはオニオンアーキテクチャとDDDの実践が必要でした。

次にクラス図を作成し、各クラスでどのような処理を行うかソースコードを想像できるレベルまで言語ベースで認識を合わせました。

その後、メンバーごとにツール・ライブラリについて調査しました。調査の結果を元に全員で話し合い、ビルドツールやテストフレームワークなどを選定しました。半数以上が初めて使用するツール・ライブラリで決定しました。

ここではその一部をご紹介します。

  • ビルドツールはバージョン管理以外にも柔軟にスクリプトを書ける点から、MavenからGradleへ変更
  • テストフレームワークはJUnit4からSpockへ変更
    • Spockは、Groovyで動作するJava・Groovyアプリケーション向けのテストフレームワークですが、強力なアサートやテストパラメータのテーブル記法などを備えている点や、ツールのサポートやコミュニティの活発さはJUnit5が優勢ですが、テストの書きやすさからSpockを採用しました

他にも検討したツール・ライブラリはありますが、ここでは割愛させていただきます。

基盤構築(モブプログラミングの実施)

このフェーズでモブプログラミングを実施しました。

アプリケーションの構成をクラス図通りに構築し、GET、POSTのAPIを1本ずつ作成します。この時点では各ツール・ライブラリについて調査結果の共有から全員が大枠の理解はあるものの、選定したメンバーが一番理解しており、レベルに差がある状態です。また、アーキテクチャやDDDにおいても同様です。

ここからは実施時に気を付けた点や、実施してみて気づいた点を紹介します。

時間の確保

まずはモブプログラミングを実施する時間をカレンダー上で確保します。Google Meetでタイピストの画面を共有しながら実施するため、Google Meetのリンクも忘れずに登録します。

時間はモブプログラミングを実施する期間中、毎日3時間を確保しました。3時間とした理由は、それより短い時間だと進捗が追いつかずに開発スケジュールに影響が出そうな点と、逆に長い時間だとミーティングなど他の予定により時間を確保するのが難しかったからです。

後になって振り返ると、モブプログラミングはかなり集中力を使い、疲れてしまう点と、別途調査の時間も必要だったため、3時間は適切だったと感じています。

もし開発スケジュールに余裕がある場合は、2時間程度から初めても良さそうです。

エディタの設定

全員がIntelliJ IDEA Ultimateを使用しており、デフォルトで行番号が表示されます。もしデフォルトで行番号が表示されないエディタを使用する場合は、ソースコードの何行目について話しているのか明確にするため、事前に行番号を表示しておきましょう。

また、事前にIntelliJ IDEA Ultimateへコードフォーマットの設定をインポートするだけでなく、GitHub Actionsでもpushされたソースコードを自動でフォーマットを修正するように設定しました。コードフォーマット論争に時間を割くのは勿体無いため、こちらも用意しておくことをおすすめします。基本的にはエディタの設定でフォーマットが整う想定ですが、設定されていないエディタでpushされたソースコードが追加された際にもフォーマットを維持するためにGitHub Actionsにも設定しています。

タイピストの使用するモニターによってはモブ側の画面で文字サイズがかなり小さくなってしまいます。必要に応じて文字サイズを拡大しましょう。

カメラとマイクはON

リモートワーク下における少人数のモブプログラミングでは、カメラとマイクは常時ONにしておくことをおすすめします。これによりコミュニケーションコストの削減や、円滑なコミュニケーションによりソースコードの品質向上にもつながります。

typoやバグをスムーズに指摘することはもちろん、タイピストの手が止まっていれば、なぜ止まっているのか状況を察することもできます。困った表情や悩んだポーズをしていればフォローを入れ、猫が遊びにきていたら一緒に幸せなひとときを楽しみましょう。

また、モブの中でも疑問を持っていそうな表情のメンバーがいれば、意見を聞いてみることで後からの手戻りを防ぐことができます。

タイピストとモブ

タイピストは30分で交代し、全員がタイピストを経験するようにしました。

私自身、他のメンバーよりJava歴が浅くて少し不安な気持ちもありました。しかし、タイピストは基本的にモブの指示に従って手を動かすため、実は自信のない人程タイピストに向いていると実感しました。

モブは積極的に意見を出し、モブプログラミングに貢献することが重要です。

優しくタイピストを導き、タイピストのレベルによってはtypoや大文字・小文字の指定などソースコードの表記に関する内容から、具体的な各行の処理の内容まで具体的に指示してあげましょう。

プログラミング初心者の場合、意見を言いづらいかもしれませんが、typoやより良い英単語の提案、過去に自分が他のモブから受けた指摘など、貢献できることはいろいろとあります。

また、一度も意見が出ていないモブのメンバーに気づいたら、何か意見がないか尋ねてみましょう。

タイピスト交代時の工夫

タイピストが交代するタイミングで、モブプログラミング用に用意したGitHubのブランチへソースコードをpushし、次のタイピストは同ブランチからpullしてその続きからコーディングを行いました。

また、交代の際にはGoogle Meetのカメラと音声をオフにして5分か10分の休憩を挟みます。時間が惜しい気持ちもありますが、集中しっぱなし・喋りっぱなしで疲れた脳では余裕もなくなり、議論やコードの質に悪影響を及ぼします。少しでもリフレッシュさせ、良い状態を維持することが大切です。

解決できない問題が発生した場合の対処法

モブプログラミングを行っていると、その場ですぐに解決できない問題が発生することもあります。

調査が必要な場合は、該当箇所以外の進められる部分を時間内に進め、期限と担当者を決めて別途調査しました。

期限内に解決が難しそうな場合は手が空いているメンバーがヘルプにつくという形式で取り組みました。最終的に全員が調査に加わった事もありました。

問題が他のメンバーによって解決された時は素直に感謝するのと同時に、自分事の様に嬉しく感じたのを覚えています。

API実装

最後にAPI実装のフェーズです。

土台となるAPIは上記のモブプログラミング形式で実装し、残りのAPIはメンバーで手分けして各自で実装しました。

全ての処理をひとりで実装するため、モブプログラミングで出てきたポイントをここで復習できました。

モブプログラミングの時間だけでは新しく導入したツール・ライブラリの全てを理解することは難しいので、ドキュメントを確認しながらの実装になります。しかし、根底の認識がモブプログラミングによって合っているため、実装に迷うことがなく、全員から上がってきたプルリクエストはある程度の統一感を保てていました。

些細な指摘はありましたが、プルリクエストのレビューで指摘をもらうことで品質を保つことができました。

モブプログラミングによる効果

実際にモブプログラミングを導入することで得られた効果を紹介します。

技術力の底上げ

ツール・ライブラリの理解度だけではなく、それぞれのプログラミング知識を吸収できるなどの学びが多く、メンバー全員の技術力の底上げに繋がりました。

終わりのない議論がなくなる

モブプログラミング実施中、終わりのない議論がありませんでした。

議論が長引いたことはありますが、意見が割れた場合、誰かが助け舟を出したり、より良い意見を出しあうことで解決に向かうことができました。

これは全員が共通の目標を持っており、相手の話に耳を傾け、理解しようとするマインドを持っていたためです。このようなマインドは心理的安全性を高め、忌憚のない意見も発言しやすく受け入れやすい環境を作るのでとても大切です。

一体感の醸成

全員が協力してモブプログラミングを行っていくうちに、不思議と一体感が生まれてきました。

実はコロナ禍のため実際に会った事も、あまり一緒に働いた事もないメンバーもいましたが、今まで知らなかったそれぞれの得意分野や、こだわり、これまで経験した苦労話など、その人を知ることにより、お互いリスペクトできる部分が生まれたのです。

一緒にコーディングをしただけで飲み会以上の効果があったのではと感じています。

安心して休める環境の構築

全員が全ての仕組みを理解している状態になったため、誰かが休むと困るということがなくなりました。

実際、全員が年末休暇を1週間ずつ交代で取得し、安心して家族と過ごすことができました。全てを他のメンバーに任せ、Slackを見る必要のない休暇からは本当の休息感を得られます。

反省点

次に活かしたい反省が3点あります。

タイピストの順番変更

タイピストの順番を変更しなかったため、2本のAPI実装で同じ人が同じレイヤーを2回とも実装することになってしまいました。

実際に手を動かすことで理解が深まり、見ているだけでは気づけないポイントもあるため、2回目は違うレイヤーに当たるよう順番を変えるべきでした。

タイマーの導入

つい熱中してしまい、気づいたら時間が超過していることがあったため、タイマーを設置するなど工夫が必要でした。前述の内容ですが、集中力維持や良い状態を維持するめには休憩を挟むことが重要です。

また、時間には上限があるため、一人のタイピストの時間が長くなることで、他のメンバーのタイピストの時間が短くなってしまいます。

時間の確保

先にも挙げましたが、ミーティングが多くまとまった時間の確保に苦労しました。

これは現在、定例などのミーティングを決まった曜日にまとめる動きがあるので、今後は時間を確保しやすくなりそうです。

まとめ

ソースコードの質やチームワーク、有休消化率までアップさせるモブプログラミング。素晴らしいです。

今回はある程度Javaに慣れているチームで未知のものを作る際にモブプログラミングを活用した事例をご紹介しました。他にもこの経験からJava未経験チームへの引き継ぎにも活用したりと、活用の場を広げています。

最後に

ZOZOテクノロジーズでは、一緒にサービスを作り上げてくれる仲間を募集中です。

ご興味のある方は、以下のリンクからぜひご応募ください!
tech.zozo.com

カテゴリー