今のチームに来てから最も生産性が上がった考え方
多分今回のポストは多くの人には参考にならないだろう。相当ニッチなので。でもこれは自分にとってはとても大きなことだったので、忘れないように記録しておきます。
生産性の悩み
あまりこの世界では生産性とはあいまいな言葉で、何をもって生産性が高いとは言いにくい。速いのが良いのではない。ただ、自分の実感として自分は生産性が良くないといつも感じていた。だからいろいろ努力したり、考え方をできる人を観察して真似してみたり、直接本人に聞いたりして工夫をしてきた。
実は自分はめっちゃコーディングが早い人になりたいわけではない。そうではなくて、「平均的」になりたいだけだ。それぐらいいければ「Strategy」でカバーできるどころかもっと上に行けると確信があったから。でもそうではなくて明らかに遅いのでそれが自分の足を引っ張っていた
努力の方向性
様々な努力をして、特に有効だったことを自分の本に書いたつもりではあるが、地道な努力はしている。例えば私は土曜は「出勤日」と決めていて、何もなければ勉強に充てて、仕事を進めたければ仕事を進めるようにしていた。プラス一日ぐらいないと同僚に追いつくどころがとてもとても同じいぐらいも出来ない感じだから。一番出来ないやつはやっぱ時間アロケートするしかないやろうという考え方。しかし、結構長。い間やっているが、なかなかうまくはいかない。「平均的」でいいのに。
いったい何がわるいのだろう?
いろいろ練習したので、自分のコーディングは遅くないし、オブジェクト指向や関数型のコーディングの知識もあるし、テスト駆動開発を使うので、出来たコードはあまりバグらない。余談だがアメリカでも、テスト駆動、とまでいかなくても、テストをしっかり書く癖のある人はそんなに多くないと感じる。
自分の開発の習慣の原点は、Extreme Programming なので、テスト駆動は身に着けておいて本当に良かったと感じている。ではなぜこんな「くっそ」遅いのだろう。
以前に問題だった、プルリクエストにレビューが沢山ついてイテレーションが長い問題も解決済みだ。
クラウドの開発は時間がかかる
私の仕事は世界規模のクラウドのプラットフォームを開発することだ。
あるとき、他のチームと仕事をする機会があり、彼女らは、小さなプルリクエストを作って、そのマネージャが速攻レビューをして、さっさとマージをするというスタイルをとっていた。なんでそんな早くできるんだろう?普通の開発だと「何が?」と思うかもしれないが、私の仕事はクラウドを開発することだ。
つまりプラットフォームを開発しているので、最終的なテストをするためには、小型のクラウドをデプロイしてそこでテストをする必要がある。この小型のクラウドをデプロイするのがぶっちゃけ一番時間がかかるパートだ。多分皆さんが想像するよりめっちゃ大変で時間もかかる。
もちろんCI/CDでプロテクトされているのだが、何せ多くの人が開発していて複雑なものなので、動かなくなる可能性も多くある。だから何時間もかけて、デプロイ失敗しましたなんてこともしょっちゅうあり、デプロイできても、そのセットアップをするのにも時間がかかる。もちろん自動化しているがそれでもかっかる。
一つのPRをバリデートするにしても、最新のブランチから自分のチェンジをマージしてきたものデプロイして、コンフィグして、テストすると多大な時間がかかる。なんせプラットフォームをデプロイしているのだ。
だけど、今回一緒にやったチームを見ていると、そんなことをやってるようにはとても見えなかった。どうやってバリデートしてるのよ…多分やってないよね。でも彼女たちのコードの品質はいい感じだ。
クリスの一言
メンタリングのタイミングが来たので自分が遅いと感じていることと、この他のチームを観察したことをクリスに話してみると彼はこんなことを言ってくれた。
「リスクをとれば良いと思うよ」彼は説明してくれた。厳密にいうと、自分がやってみるみたいに、ちゃんと小さなクラウドの環境を自分のブランチからデプロイしないとちゃんとしたバリデーションにならないから、マージしたらCIコケるかもしれない。何か壊すかもしれない。
でも、多少バージョンが古くとも、再度のデプロイが発生しないようにDLL の置き換えだけで自分の変更点をテストできるならそれで良いだろう。もしかすると問題が起こるかもしれない。でもそれは「楽観ロック」のようなものだよ。と言ってくれた。
楽観ロック式で考える
ロックの方式でいうと、「悲観ロック」を使うと、データの整合性は保たれるけど、データの更新の時にロックするからパフォーマンスが落ちる。「楽観ロック」の場合は、同時に2つが更新した場合、1方は、やり直しになるのでより時間がかかるんだけど、それと同じだよね。プルリクエストも、「楽観ロック」と同じように考えて、自分なりにユニットテストやインテグレーションテスト、クラウドのデプロイより短いスパンで自分の変更に自信が持てるもので自信を担保して、たまに失敗するのを受け入れる。でもトータルとしたら、生産性はそっちの方がずっと高くなるよ。
Bala の作戦
違う時にすっごくできるBalaに質問をしてみたことがある。彼はプルリクエストを1日に4個も5個も上げてくる。(そして正確)彼も「できるだけ、小さなクラウドをデプロイしないように持っていく。その後作ったPRに対してデプロイを流してこけないことだけ保障する」と話してくれた。
人間優秀だろうがそうでなかろうが、出来ないものは出来ないのだ。
ある時私が、その小さなクラウドがうまく動作しないことがあって、再デプロイするしかないかぁ~という時も彼は、小さなクラウドを直す方向性に持っていくのではなく、「この機能は、あの機能がうまく動かなくても君の書いたコードの部分は評価できるよね。それで良くない?」と言った。多分同じ考え方のようだ。つまり自分は「ちゃんとやらないといけない」と思いすぎていて、常に環境までちゃんとしないといけないと思っていたが、「リスクをとる」という単純なストラテジーがうまくできていなかったのだ。
リスクをとることが生産性の問題を「解決」した
クリスとBalaのアドバイスを受けて、私もリスクをとる方法に切り替えた。できるだけクラウドをデプロイせず、前にクラウドをデプロイしたブランチから派生させて、DLLを置き換えてテストして、それを Cherry-pick してDev ブランチにPRを作る。後は、しっかりと環境ごとデプロイしてテストしてくれるCIを信頼して、自分的にはしっかりテスト駆動で開発する。
たったそれだけのことで、自分の中でみんなより「遅い」という感覚が消滅して、スピードに自信が持てるようになった。そして、今後は、より「良いエンジニアになるためには?」ということにフォーカスできる心持になれた。引き立つ「遅さ」が解消されたので、休日もゆっくり、何か新しい事でもしようという心持にもなれた。やっとなれた。もう4年もこのチームでやってるけどやっと。やっと。
まとめ
今回のブログはきっと多くの人に役に立たないだろう。自分のようにプラットフォームを開発していて、開発のボトルネックがプラットフォームのデプロイにあるというパターンの人はそんなにはいないと思う。ローカル環境でちゃんとテストできるならそれで充分だし、アプリのデプロイが必要でも、あまり時間がかからなければ問題にはならないだろう。だから今回の話は、何らかの大きな時間のかかるボトルネックがあるケースの開発をしている人のための話でしかないと思う。
でも人に役にたたなくても、自分にとってはめっちゃくちゃ大きな改善で、今までもいろいろ工夫して学んで、実践してやっとここまでこれて本当に良かった。
いままでの学びを一流の編集者さんがめっちゃくそ読みやすくしてくれて本にしてくれました。おかげさまで8万部突破したらしいです。もしよかったら読んでない人は読んでみてくだされ。