若手開発者の後悔

(編注:2020/08/18、いただいたフィードバックをもとに記事を修正いたしました。)

これはある仕事熱心な若手開発者のほぼ実話です。2004年の後半、この若手開発者は小さな会社で働き始めました。条件は全て彼の望みどおりでした。給料はいいし、扱うのは彼の得意とするプログラミング言語、アプローチの複雑性、モデリングのアーキテキチャでした。

彼にとって今回の会社が初めての職場ではありませんでした。しかし、ここでの最初のプロジェクトは結果的に問題だらけに終わりました。当時、この若手開発者は、機能は絶対に変わらないものだと思っていました。しかし、それは間違いでした。機能が変更されるたびに完全なリファクタリングを行わなければなりませんし、バグを引き起こして膨大な時間を無駄にしてしまいます。彼は、テストを書くといった実直な方法も試してみましたが、書いたテストはメンテナンスが必要な上、書くのに時間がかかりました。そして、それを実行するのはさらに時間がかかりました。

彼も他の若手開発者と同様に、ベテラン開発者の忠告を聞いて成長してきました。「気を付けろ! 早すぎる最適化は悪だ! 」とか「テストを書け! テストだ、テスト! 」などと言われてきました。彼が小さなユーティリティーメソッドをリファクタリングしているだけでも、ベテラン開発者は厳しい顔つきで「早すぎる最適化をやってはいないよね? 」とか「テストは当然、書いているよね?」と言いに来ました。

しかし、これらの忠告の言葉は彼には届いていませんでした。この若手開発者は、なぜ早すぎる最適化が悪で、テストが正義なのか理解できませんでした。今までの自身の経験から、仕様に従うことは長期的には役に立たない(仕様は変更されがちだから)し、テストを書くのは時間の無駄だと思っていました。

若手開発者はこんなふうに考えていました。「一体、なんで毎回コードを書き直す必要があるんだ? それに、今現在で最高のコードが僕には書けるのにどうして今書くコードを後でリファクタリングしなきゃいけないんだ? そして、なぜ役に立たないテストを書くために時間をかけなくちゃいけなんだ? 」と。

ある日、この若手開発者は新しいプロジェクトの作業に取りかかります。この時、彼はついにベテラン開発者の忠告を無視しようと決断しました。全てのコードを高速で、コンフィギュレーションが可能で、ロバスト性のあるものにしたかったので、どんな仕様の変更にも対応できるようにしました。仕様は明確ですが、彼はそれ以上のところまでやりました。例えば、フィーチャーが大文字のSで終わるプロダクトコードを作る時には、コンフィギュレータのオブジェクトを生成しました。そうすれば、末尾のアルファベットがコンフィグレーションによって決まるのです。また、仕様がバリデーションを必要とする際には、彼は仕様が必要としているものだけでなく、さらに多くのものをコントロールできる巨大なバリデータを作成しました。

プロジェクトの中核を書き終えると、若手開発者は自分の仕事の完璧さに惚れ惚れしていました。彼は自分の素晴らしいコードを見ながら「ベテラン開発者は間違っている! 」と勝利を確信したのです。その後、彼は昼も夜も働き続け、プロジェクトを完成させます。リリースまでは数週間ありました。

時間が過ぎ…

ユーザからバグがあると指摘がありました。ベテラン開発者はそのバグを確認し、画面に現れたものを目にして驚愕しました。若手開発者が大聖堂のように完璧に作ったと思ったものは、ベテラン開発者から見ればスラムのように混沌としていました。若手開発者には秩序があったように見えていたものは、ベテラン開発者にしてみればただの錯綜したネットワークでした。若手開発者が超高速のコードだと思っていたものは、ベテラン開発者から見れば無駄に複雑化したアルゴリズムでした。そして、ベテラン開発者はそのコードには触れたくなかったので、若手開発者に自分でバグを修正するように指示しました。

他人に自分のコードが美しいと思われなかったと考えただけで、若手開発者は憤慨しました。彼は怒りに満ちてプロジェクトを開きました。ところが、そのコードは彼自身にも理解できないものだったのです。コードには明快な意味がありませんでした。彼の最初の反応は、「だから、僕はもうこの言語は使っていないんだ。構文が醜いから」というものでした。でも、心の底では、それが本当の問題ではないと知っていました。本当の問題は、自分でした。

その日の終わりにバグは修正されましたが、これがまた別のバグを生み、後日発覚することになりました。修正を繰り返すたびに、プロジェクトの中の微妙なバランスが変化しました。光沢のある白いドレスについた小さな黒いシミのように。

若手開発者は、絶望していました。彼の大聖堂はぐらつき始めていて、今にも崩壊しそうな気がしました。「僕はこの仕事にふさわしい人間じゃないのかも知れない。なんで正しくコードを書けないんだろう」彼は自問しました。彼は、憂鬱さと怒りの混ざった気分で、ベテラン開発者がメンテナンスしたプロジェクトを開きました。

プロジェクトを見た彼は愕然としました。コードはコメントとテスト付きで、読みやすい。彼が新人のころに書いていたコードとさほど違いませんが、いくつかの点で明確に違っていました。広範囲なコンフィギュレーションがないこと、コードは行ごとにテストされていること、どのメソッドも名前に意味があり、短く(最長で10行のコード)、要求されたことだけを実行すること、そして、どのファイルにもジョブを行うために厳密に要求されたメソッドだけが含まれていること。

若手開発者が落胆していると、ベテラン開発者がやってきました。ベテラン開発者は彼の近くに座って、バグを引き起こしているコードをリファクタリングし始めました。

彼らは何日も一緒に作業しました。あるときはベテラン開発者がコードを書き、若手開発者はベテランが問題を解決する様子を見ていました。またあるときは、若手開発者がコードを書いて、ベテラン開発者が監督しました。

数日後、新しいデプロイで、そのバグは修正済みとマークされました。バグを引き起こしていたコードの小さな部分は、テストされ、読みやすく、安定しています。ベテランの開発者は若手開発者を見て言いました。「もう分かった? 」と。

若手開発者は頷きました。分かり始めていました。完璧さへの鍵は将来を予測することではなく、変更とテストが簡単で(変更によってバグが引き起こされないように)、現在の要件だけを満たすコードを書くことです。このことが分かり始めると、彼は自分が変化しつつあること、ほぼベテランの開発者になっていることを自覚しました。

「プロジェクト全体をリファクタリングしてもいいでしょうか? 」と、若手開発者が問います。
「もちろんダメだ。そんな予算はない」と、ベテラン開発者がつっぱねます。
「でも、また別のバグが出てきたらどうするんですか? 」と、若手開発者が問います。
「フリーランスを呼んで修正させる」と、ベテラン開発者が答えます。

その後、この、ほぼベテランの開発者は良いコードを書くようになり、またひとつ別のレッスンを学ぶ準備が整いました。でも、それは、この話とは別のお話です。

若手開発者への教訓:過去に書いたコードを絶えず見直すこと。そして、そのコードが当時思っていたほど美しく見えなくても落胆しないこと。

ベテラン開発者への教訓:身近に若手開発者がいたら、彼の尻ぬぐいをする羽目になるだろう。でも、いずれ近いうちには、彼もまともなコードが書けるようになるから心配なく。

フリーランス開発者への教訓:作業単価を値上げした方がいいのでは?