レガシーソフトウェアをチームで改善するためにまずしたこと

はじめに

今年度、新卒で入社した suke です。インターネットではよく omuomugin というアカウントを使っています。現在はゼクシィアプリの内製開発チームでソフトウェアエンジニアとスクラムマスターをしています。

ゼクシィのiOSアプリは2011年から開発されており、レガシーになっている部分も多くありました。本記事では、去年の5月に立ち上がったゼクシィアプリの内製開発チームで取り組んできたレガシーなソフトウェアに向き合うためにやってきたことを書いていきます。レガシーなソフトウェアの定義は様々ですが、レガシーソフトウェア改善ガイドによれば、優れたテストコードがなかったり、ソースコードが変更に対して柔軟でなかったり、いわゆる技術負債が溜まってしまっているソフトウェアのことを指します。

僕らのチームでは、改善の最初のステップとして大きく以下の3つのことをしてきました。
「レガシーソフトウェア改善ガイドの輪読会」を通してメンバー間で認識を揃え、
「ペアプログラミングを推進」してコードの理解を相互に深め、
「技術的リファインメント会」でスプリントプランニング時の不確実性を下げる

レガシーなソフトウェアとの最初の向き合い方に関する情報が少なかったので、これからレガシーなソフトウェアに向き合う人たちの参考になればと思います。

TL;DR

レガシーソフトウェア改善ガイド輪読会

「レガシーソフトウェア改善ガイドの輪読会」を通してチームメンバーの認識を揃える

開発に加わって最初の課題は、レガシーなソフトウェアに対する知識や経験がチームメンバーによってばらばらなことでした。ある程度アプローチを知っているメンバーもいれば、何から初めていいか検討もつかないメンバーもいました。それによって各々の認識がずれていたりアプローチがそれぞれの頭の中だけにある状態になっていました。

そこでまずはチーム内で認識を揃えたり議論を活性化させることを目的に「レガシーソフトウェア改善ガイド」の輪読会を開催しました。輪読会の形式は、毎週1時間で前半30分で要約をみんなで読み、後半30分であらかじめ書かれた議論点などを話していくというものでした。だいたい毎回1章ずつ読んでいたので全部で10回開催されました。

議論を活性化させる工夫として社内のScrapboxに要約や議論を書くようにして、輪読会に参加しているメンバーも参加していないメンバーも何かしらの形で議論に参加できるようにしました。その結果、最初はチーム内だけでの取り組みでしたが、チームや部署を超えて多くの人によって議論が盛り上がりました。

議論を通して、各々の頭の中だけにあったアプローチだったり、特定のメンバーしか持っていなかった知識をチーム全体に共有することができました。また本の内容からレガシーソフトウェアの改善の勘所だったりを学び、いくつかの教訓を得ました。その中で、以下の学びや教訓をチームで実践しています。

調査的リファクタリング

レガシーソフトウェア改善ガイドの中で紹介されているリファクタリングの手法の1つです。レガシーなソフトウェアはコメントやメソッド名などドキュメンテーションとなるべきものがメンテナンスされておらず誤っていることもあるので、ソースコードを読みながら得た知識を正しいコメント、適切なメソッド名や変数名に変更していくという手法です。僕らのチームでは、今でも調査的リファクタリングをペアプログラミングやモブプログラミングの場で実施していて、アプローチの1つとして重宝しています。「調査的リファクタリング」は、次節でも触れますがペアプログラミングの際などに活用しています。

レガシーになっているのはコードだけじゃない

経験によっても学んだのですがドキュメントやプロセスがコードから遠くてアクセスしにくかったりという環境がドキュメントのメンテナンス性を低下させているということが本に書かれていました。また知識のサイロ化のせいでドキュメントがあっても正しく理解できなかったりという問題も紹介されていました。アプローチとしてなるべく1箇所になるべくコードの近くに置くというものが紹介されておりそれに従いながらドキュメントの移動や統一を進めています。

リファクタリングの対象も戦略的に選ぶ

リファクタリングをする理由の1つは保守コストを下げることです。したがって、よく触るコードはそれだけリファクタリングする価値があります。これは言われてみると当然なのですが、どうやってそれらに価値をつけていくか優先度を整理していくかについて様々なアプローチが紹介されています。その中でもとにかくまずは定量的にコードを測れるようにするという点が印象的で、僕らのチームでもテストカバレッジを測定したりコードの複雑度などを様々なツールを使って定量化を進めています。

先日投稿されたブログでテストカバレッジの取り組みについて紹介しています。

Codecov で iOS アプリのテストカバレッジを可視化する (GitHub + CircleCI + Codecov)

ペアプログラミング、モブプログラミングの推進

「ペアプログラミングを推進」してコードの理解を相互に深める

実際にアプローチがある程度見えてきて機能開発ができるようになってくると、次の課題としてドメイン知識がチームに不足していたり、コードの意図を読み取るのが難しかったりなど、1人で自信を持って作業することが難しいことがわかりました。またゼクシィではABテストを多く実施しており、必要なくなったコードや元々使用されていないコードの削除などもデグレの懸念などから確実な自信を持って行えない作業の1つでした。

そこで解決策として、ペアプログラミングの推進を行なっていきました。最初はスクラムマスター から「ペアプログラミングしたらどうですか?」と促していました。定期的にペアプログラミングが有効だったタスクなどを振り返ることで、今では難しいタスクや自信のない作業がある場合には自然とチームの中で「ペアプログラミングお願いします」と依頼が行われるようになりました。特に成功体験をチーム全体でシェアすることが積極的なペアプログラミングに繋がりました。

具体的な例として以下のような場面でペアプログラミングが効果を発揮しています。

コードの意図がわかりづらいとき

既存実装の調査をしているときに、その理解に自信が持てないことがあります。例えばコメントが誤っている場合などは自信を持ちづらいです。そういった場合には、ペアプログラミングを通して既存実装の理解が誤っていないことを2人でコードを読み確かめます。また、この際に調査的リファクタリングを通じて正しいコメントをつけたり、ソースコードに得た知識を反映していったりしています。

コードの削除箇所が大きいとき

不要なコードを削除する際には、そのコードが使われていないことを調査します。 調査をすることで学習したことを改めてレビュアに伝えるよりも、最初からペアで調査・学習しながら作業を進めた方が効率的です。またペアプログラミングのおかげで自信を持った状態で正しく削除などが行えるようになりました。実際の例としては、リファクタリングとして1200行ほどのコードの削除を行なったりなどがあります。またその際に認識していなかった仕様を見つけることができています。

実装方針に悩んだとき

テストを前提にしていないコードに対してテスタブルなコードを少しづつ入れていくのは簡単なことではないです。その中では合理的な妥協点もあるので設計方針や実装方針に悩むことが多々チームの中で発生していました。そういった時にペアプログラミングをすることでレビューを受けながらよりよいコードを素早く作ることができています。

技術的リファインメント会

「技術的リファインメント会」でスプリントプランニング時の不確実性を下げる

ペアプログラミングがチームに浸透してきて作業がある程度安定して着手可能になってくると、次は既存実装に対する知見がないことが原因でスプリントプランニングが長引いたり、見積もりと実際の作業に大幅なぶれが生じたりしていました。

リファインメントとは、次のスプリントで取り組むべき作業の不確実性を下げるという活動のことです。 この活動がないとスプリントプランニングやスプリントの負荷が大きくなってしまいます。詳細については、スクラムガイドCore Scrum を参照してください。通常スクラムのフレームワークで推奨されるリファインメント時間は開発チームの作業の10%以下ですが、チームにドメイン知識が蓄積されるまでの間はそれよりも多くリファインメントの時間を取ることにしました。具体的な方法としては、2週間に1回1時間、開発チーム全員で集まって次のスプリントで取り組む予定のストーリーについて技術調査をモブプログラミング形式でやるというものです。全員でスタンディングデスクに集まり、1つのディスプレイで次のスプリントバックログに乗っているストーリーの懸念点を洗い出して行きます。ここでもコードを全員で一緒に読みながら調査的リファクタリングを実施してソースコードに得た知識を反映していきます。

モブプログラミングでは、手を動かして実際にコードを書くドライバーと指示を出す多数のナビゲーターという役割に分かれて1つのPCで全員で同じ作業をします。この中でドライバーは唯一、作業を止める権利を持っています。最近ではドライバーを固定せずに、なるべく新しい人などにドライバーを担ってもらい、分からないことがあったときには作業を止めて質問してもらうという工夫をしています。

 

まとめ

まとめ

レガシーなソフトウェアの改善を始める最初の立ち上がりとして

「レガシーソフトウェア改善ガイドの輪読会」を通してメンバー間で認識を揃え、
「ペアプログラミングを推進」してコードの理解を相互に深め、
「技術的リファインメント会」でスプリントプランニング時の不確実性を下げる

という話を紹介しました。レガシーソフトウェアの改善をこれから始める人の参考になればと思います。

参考リンク

レガシーソフトウェア改善ガイド

スクラムガイド

Core Scrum