レガシー

SIer所属のSEに「レガシーコードからの脱却」が突き刺さった

9月にオライリーから発売された「レガシーコードからの脱却」をようやく読了した。エッセンスの宝庫で、何度でも読み直したいスルメ本であった。今回は、SIerでアプリケーションフレームワーク開発業務に従事している自分が、いかにしてコードと向き合っていくかという観点で、同書の刺さった項目を書き連ねたいと思う。

内容に入る前に一つだけ自慢させてほしい。トップ画像の通り、翻訳であるアトラクタ社の4名を、いろいろなところで捕まえて次々とサインをもらい、ついにコンプリートした。訳者のうちの一人、有野氏には、「吉羽氏は捕まえにくい」と言われたが、ようやくEOF2019というカンファレンスで吉羽氏にサインを頂戴することができた。その際、おそらくコンプリートは初めてでは、と言われた。しかし、実はコンプリートは完了していない。いずれ著者のDavidScottBernsteinにもサインをもらえる日が来ると信じている。

概要

同書のタイトルは、レガシーコードからの”脱却”であるが、複雑怪奇なクソコードを様々な手法を用いてリファクタリングしていく。という内容ではない。いかにしてレガシーコードを作らないかにフォーカスされた内容である。ここでいうレガシーコードの定義(*1)は、「理由は問わず、修正、拡張、作業が難しいコード」のことである。具体的にはレガシーコードを作らないための方策として、9つのプラクティスが紹介されている。この9つのプラクティスはExtremeProgramingを中心としたアジャイル開発手法のプラクティスを元に構成されている。

プラクティス自体は、目新しいものではない。数々の名高い古典から、現在のシステム開発においてこそ役立てることができるエッセンスを抽出し、再構成されている。故に、それぞれのプラクティスをより深堀りしたい方は、紹介されている古典にあたるのがよいだろう。古典を通っていない私にとって、同書の内容は刺激的で驚きに溢れていた。決して、古典のための導入書ではなく、この本自体に一読の価値はあると断言できる。

ここからは私が読みすすめる中で、刺さった項目を取り上げて、その要約と感想をそれぞれ一段落ずつ記載していきたいと思う。

5.4 ストーリーで目的、理由、誰のためかを語る

本項では、ウォーターフォール開発における詳細な設計ドキュメントは無駄であると説いている。結果として、コードに触れる時間が少なくなり、コードに仕様を語らせたり扱いやすくするための時間を奪っている。詳細なドキュメントなど不要で、プロダクトオーナと開発者、そして顧客が会話するための辛うじて十分なドキュメントとしてストーリーを定義するべきである。ストーリーとは「何が」「なんのために」「誰のために存在する」の3点で構成される1文のことである。ここで定めたストーリを軸としてコミュニケーションをとることで要求に対する深い理解が得られるのである。

秋の夜長に読みながら思わずニヤニヤしてしまった。本項では、ウォーターフォール開発への皮肉がふんだんに散りばめられている。特にお気に入りの一節は下記である。

従来のウォーターフォールプロセスは計画そのものは独立して生きていくことが多いため、計画会議が終わるとはっきりとした達成感がある。
要求を作るのに巻き込まれた人たちはプロジェクトが終わったかのように感じるかもしれない。
しかし、やったことといえば、誰かが何かに実際に作業した時点でこういったものがどんなふうになっていればよいか合意した気になれたというだけだ。

所詮、会議で見通せることは、空論である事が多い。なのに、「謎の達成感」と根拠のない「やれそうだ感」が心を支配する。そして、自席に戻った後で、結局何をすればよいのかわからないことに気がつくのである。

6.9 バックログを作る。

バックログ(ストーリーのリスト)の並べ替えについて紹介している項である。プロダクトとして機能する最小のストーリーを「最小市場化可能機能セット(MMF)」を満たす順序で並べ替える。バックログというものは、「優先順位をつける」のではなく「並び替える」と考えるのがよい。1番重要なものよりも、2番目に重要なものから作った方が、効率的であったり、重複コードを防ぐ場合があるからだ。

優先順位ではなく、並べ替えというのは、なかなか理解しづらかった。たしかに、バックログに書かれた内容だけで、2つの機能のどちらが重要か明確な基準を設けることは難しい場面はある。その場合は、もう一段工程を下げて、設計や実装レベルに思考を落として検討すると、「機能自体の重要性」よりも「先行着手する有効性」が見えてくるのかもしれない。

8.8 学習を増やし、知識を広げる

勉強し続けることの重要性、そして、得られた知識をチームに共有することが現在においては評価につながるという話。そして、著者の好きなこととして「カンファレンスに行って、セッションをすっ飛ばす」というプラクティスが紹介されている。どういうことかというと、セッションには出ず、友人や同僚を見つけ出し、ひたすらトークするのだという。セッションに参加するよりもそのトークから得られた情報のほうが気づきや驚きを得られることが多いという。

2019/10/31に開催されたEOF2019というカンファレンスの主催者のオープニング・セッションの中で、まさしくこの話題が出た。元ネタは同カンファレンスの数週間前にt.wada氏がtwitterに投稿した下記の投稿である。

同セッションでは、いきなりこのtweetを引用し、隣の人と雑談してください。というエポックメーキングな体験があった。そのおかげもあり、元同期との廊下トークや、同日登壇されていた吉羽氏のask the speaker(*2)で質疑を行うことに積極的になれた。

10.7 テスト駆動開発は失敗することがある

同書の10章、11章ではテスト駆動開発がレガシーコードを作らないために有効であることが書かれている。テスト駆動開発についての解説は割愛するとして、本項では、テスト駆動開発のアンチパターンが書かれている。テストコードだからといって、冗長であってはならない。価値の低いテストたくさん実施したところで、将来メンテナンス地獄になるだけである。例えば、インタフェースに対するテストのバリエーションが重要になるにも関わらず、内部実装に対するテストを重点的に行っていても意味がない。あくまでふるまいに対してテストをするべきである。

ユニットテストの粒度設計は困難を極める。私自身、保守フェーズのプロジェクトに途中参画しているため、テスト粒度や観点は、どうしても既存のテストコードを参考にせざるを得ない。しかし、既存コードには、一定の統率はありながらも、開発者によって観点の揺れはどうしても発生している。その揺れの中で、既存ケースの物足りなさを感じる場面もある。とても悩ましい場面であるが、ここでの正解はリファクタリングやケースの追加なのだろう。意識していきたい。

11.8 コードをテストでカバーする

同書では、カバレッジは100%しか意味がないと述べている。その理由は、100%以外の目標値に対して統率を取ることが難しいからだ。例えば、仮に80%などに設定すると、テスト難易度が高い核心部を回避し、意味の薄いアクセサ(getter/setter)にテストを行い、カバレッジ率を上げる。基準を超えることが目的になりやすく、同一コードの別ケースを書かなくなる場合もある。逆に、アクセサのような自明なコードにはテストを書かないことも著者は否定している。テストはコードの仕様を定義するために行うので、アクセサに対してもテストを行い常に100%のカバレッジ率を目指すべきだと説いている。

なるほど、挑戦的だ。前半の内容は共感できる。カバレッジ率を目標に置くと、それ自体が目的になりやすくなるというのは非常に納得がいく。しかしながら現実問題として100%を何が何でも達成するというは効果があることなのだろうか。それこそ10.7で問題と述べていた、「内部実装を網羅するためのテスト」が量産されやしないだろうか。カバレッジを100%にするためには、内部実装がシンプルなプロダクトコードを意識するはずだという意見もわからなくはないが、果たして開発者の認識を合わせることに苦労しそうである。

まとめ

同書は、すでにたくさんの方が書評をブログやSNSで公開しており、また界隈の有識者からの絶賛の声も多い。売上も好調なようで、一時期、書店やamazonからも姿を消していたほどだ。私も時間をかけて拝読させていただいたが、気づきと驚きを感じつつもまだまだ理解の及ばない点もあり、奥深さを感じた。自身の成長に連れ、さらなる気づきを与えてくれる気がしている。故に、後に振り返って再読することを誓い、本投稿を締める。

*1) 吉羽氏の同名セッションによる定義
*2) ask the speaker:セッションの登壇者に直接質問を行う事ができる時間

この記事が気に入ったらサポートをしてみませんか?