将棋の名人は十手以上も先を読んで次の一手を決めるという。ソフトウェア開発ではあまり先読みなどしないで、とりあえず適当にいじくってみる、という方法も有用だが、探索空間が広い問題ではあまりうまくいかない。
たとえば、手強いバグを相手にするときには無数に可能性があるので、いちいち手を動かして試行錯誤していてはらちがあかない。こういう場合は、一度手を休めて、コードを頭に叩き込んで、あらゆる可能性を考慮しつつ、慎重に仮説を立ててから検証するというモードに移らないといけない。
もうひとつじっくり考える必要があるのは、大きな変更に取り組むときだ。たとえば、既存のコードの設計を大幅に変更する場合は大局的な視点が必要で、その上で、影響を受ける箇所を細かく洗い出して計画を立てなければならない。
しかも厄介なのは、大規模なプロジェクトの場合、巨大な変更を一つのパッチで行うのは難しいので(コードレビューが難しいし、リスクが高い)、最終的には巨大となる変更を、一連の安全なステップに分割して行う(Kent Beck によると、これを Succession と呼ぶらしい [1])必要がある。安全というところがポイントで、個々のステップでは機能もテストも壊してはならない。
同僚の一人はこの Succession の名人で、どんなにややこしい大きな変更でも、小さな変更に分割して、すいすいと遂行してしまう。ある大きな機能を完全に作り直したときは、数十のパッチに分割して工事が行われ、しかも、途中の行程は可能な限り並列化(複数のコードレビューを同時に進行して、終わったものから次々とチェックインできる)されていた。
この間、古い実装の動作は常に維持され、最後のパッチで新実装に切り替えたときは、一発で正しく動いた。コードはシンプルになり、速度は向上した。新しい実装が安定しているのを確認したのち、古いコードは数週間後に削除された。
どうやったらこんな鮮やかに大工事を遂行できるのかと思い、本人にきいてみると、手元で一通り全部動くところまで一度作ってから、巨大なパッチを清書しながら分割して、段階的にコードレビューに投げていくのだという。分割する際にはパッチ間の依存関係を最小限に抑えるのがポイントで、そうすることにより工程の並列化ができるようだ。
でも、どうやっても依存関係は残るし、それはどうするの?とたずねると、「10枚くらいはいつも(パッチを)積んでますよ。1枚入れた後はいつも rebase 祭りですね(git でブランチを別のブランチにつけ直すこと)」とのこと。
多段に依存したパッチを抱えつつ、複数のブランチを活用して並列に物事を進められるというのはすごいことだ。脳内のスタックがよほど大きいに違いない、と感銘を受けつつも、パッチの数え方ははたして「枚」なのか?そしてそれは積むものなのか?という疑問が残ったのであった。
[1] http://www.facebook.com/notes/facebook-engineering/software-design-glossary/10150309412413920